Installing the Microsoft Intune client directly after a task sequence

This blog post will be about a bit strange scenario, it will be about deploying a device via a task sequence of ConfigMgr and ending up with the Microsoft Intune client. There are some cases in which the customer elects to manage some devices through Microsoft Intune, instead of ConfigMgr, but still wants to deploy the operating system via ConfigMgr. In those cases creativity is required to get the Microsoft Intune client installed.

The ConfigMgr client and the Microsoft Intune client can’t coexist on one device and it’s not possible to remove the ConfigMgr client during the task sequence (without breaking the task sequence).  That’s were the SMSTSPostAction task sequence variable comes in place. This variable can be used to trigger an (unmonitored) action after the task sequence is completed. In this blog post I’ll provide a simple PowerShell script to remove the ConfigMgr client and to install the Microsoft Intune client. Also, I’ll show how to use this PowerShell script in a task sequence.

Script

Now let’s start with the PowerShell script, by going through it step-by-step. The first step is the declaration of the required variables. Most of these variables are set to the default values. The $NewPath variable will be used as a temporary folder.

$NewPath = "C:\Temp" $CertificateName = "MicrosoftIntune.accountcert" $UninstallPath = "C:\Windows\ccmsetup" $UninstallerName = "ccmsetup.exe" $UninstallerArguments = "/Uninstall" $InstallerName = "Microsoft_Intune_Setup.exe" $InstallerArguments = "/Quiet"

The next step is to copy the Microsoft Intune client installation files to the temporary folder. This is done to overcome installation problems from the initial location after copying the installation files during the task sequence. This can be done by creating the temporary folder via the New-Item cmdlet and by copying the installation files via the Copy-Item cmdlet.

New-Item $NewPath -Type Directory Copy-Item "$PSScriptRoot\$InstallerName" -Destination $NewPath Copy-Item "$PSScriptRoot\$CertificateName" -Destination $NewPath

After everything is in place the removal can be started of the ConfigMgr client. This can be done by triggering the Start-Process cmdlet and waiting for that action to finish.

Start-Process -FilePath "$UninstallPath\$UninstallerName" ` -ArgumentList $UninstallerArguments -Wait -PassThru

After the removal of the ConfigMgr client it’s possible to start the installation of the Microsoft Intune client. This can be done by triggering the Start-Process cmdlet again and letting it wait for the action to finish. Keep in mind that when that process finishes the Microsoft Intune client is not fully installed yet. The processes are started to trigger all the different agent installations.

Start-Process -FilePath "$NewPath\$InstallerName" ` -ArgumentList $InstallerArguments -Wait -PassThru

At the end when the removals and installations are done, it’s time to clean up the installation files that were copied. This can be done by using a simple Remove-Item action on the temporary folder.

Remove-Item $NewPath -Force -Recurse

Save the script as Install-IntuneClient.ps1 and add the script together with the Microsoft Intune client installation files into one old-school Package. This Package does not require a Program and will only be used to provide the content during the task sequence. That means that this Package will contain the following three files, Microsoft_Intune_Setup.exe, MicrosoftIntune.accountcert and Install-IntuneClient.ps1.

Task Sequence

Now let’s have a look at how to use this PowerShell script in a task sequence. Well, the actual PowerShell script will not be started during the task sequence, but it will be added as an action directly after the task sequence is finished.

1 CopyClientFilesThe first action is to copy the content of the old-school Package, used to hold the previously mentioned files, to a local location on the device. This can be achieved by a simple Run Command Line step with a similar command to XCOPY.EXE “.\*.*” “%TEMP%” /HERCIY.
2 PostActionThe second action is to trigger an (unmonitored) action after the task sequence is completed. This can be achieved by a Set Task Sequence Variable step that will set the variable SMSTSPostAction to a similar command as PowerShell.exe -ExecutionPolicy ByPass -File “%TEMP%\Install-IntuneClient.ps1”.

All together this will make sure that after a successful task sequence the created PowerShell script will be started. I’ve tested this now a numerous times and it works like a charm, just keep in mind that it’s triggered after the task sequence is started. That means that this action is not part of the task sequence progress and by that not monitored. To achieve something like that, the PowerShell script can be adjusted to log and sent more information.

How the settings in ConfigMgr translate to the command line in USMT

The last couple of days I’ve seen and read a few situations in which it was clear that it’s not always that obvious what the USMT command line will be based on the settings in ConfigMgr. This blog post will be about the different settings in a task sequence for capturing and restoring the user state and how they translate to the command line for USMT.

Capture User State

CaptureLet’s start with two basic capture settings and continue from there. These basic settings are Capture all user profiles by using standard options and Copy by using file system access. These settings combine to a command line like this C:\_SMSTaskSequence\Packages\PCP00001\amd64\scanstate.exe C:\_SMSTaskSequence\UserState /o /localonly /efs:copyraw /l:C:\WINDOWS\CCM\Logs\SMSTSLog\scanstate.log /progress:C:\WINDOWS\CCM\Logs\SMSTSLog\scanstateprogress.log /i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\migdocs.xml /i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\migapp.xml.

Based on that command line we can see that by default it will overwrite any existing data in the migration store (/o) and it will only migrate data from the local computer (/localonly). Also, it does standard things like using log files (/l and /progress) and using standard configuration files (/i). The following table lists the adjustments to this command line when selecting different options in the task sequence editor.

Option Command
Enable verbose logging /v:5
Skip files that use the Encrypting File System /efs:skip
Continue if some files cannot be captured /c
Capture locally by using links instead of copying files /hardlink /nocompress
Capture in off-line mode (Windows PE only) /offlineWinDir:D:\WINDOWS
Capture by using Volume Copy Shadow Services (VSS) /vsc
Customize how user profiles are captured /i:D:\_SMSTaskSequence\Packages\PCP00001\x86\Example1.xml
/i:D:\_SMSTaskSequence\Packages\PCP00001\x86\Example2.xml

Restore User State

RestoreLet’s start with one basic restore setting and continue from there. This basic setting is Restore all captured user profiles with standard options. This setting translates to a command line like this C:\_SMSTaskSequence\Packages\PCP00001\amd64\loadstate.exe C:\_SMSTaskSequence\UserState /l:C:\WINDOWS\CCM\Logs\SMSTSLog\loadstate.log /progress:C:\WINDOWS\CCM\Logs\SMSTSLog\loadstateprogress.log /i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\migdocs.xml /i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\migapp.xml

Based on that command line we can see that by default it does standard things like using log files (/l and /progress) and using standard configuration files (/i). The following table lists the adjustments to this command line when selecting different options in the task sequence editor.

Option Command
Continue if some files cannot be restored /c
Restore local computer user profiles /lae /lac:Password01
Enabled verbose logging /v:5
Customize how user profiles are restored /i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\Example1.xml
/i:C:\_SMSTaskSequence\Packages\PCP00001\amd64\Example2.xml

Extra options

Somebody familiar with USMT might notice that this doesn’t even cover half of the settings available for USMT. The nice thing is that it’s also possible to use these other command line switches. There are three task sequence variables that give extra options during the capturing and restoring of user state.

  1. OSDStateStorePath – Specify the UNC or local path name of the folder where the user state is saved. My personal preference is a folder out-side the task sequence cache, like %SystemDrive%\UserState.
  2. OSDMigrateAdditionalCaptureOptions – Specify additional USMT command line options that are used when capturing the user state. This could be used to exclude accounts from the migration, by using one of the /ue command line options.
  3. OSDMigrateAdditionalRestoreOptions – Specifies additional USMT command line options that are used when restoring the user state. This could be used to exclude accounts from the migration, by using one of the /ue command line options.

More information about the task sequence action variables, see: http://technet.microsoft.com/en-us/library/hh273365.aspx
More information about the USMT command line options, see: http://technet.microsoft.com/en-us/library/hh825175.aspx

Install computer-targeted application during OS deployment via PowerShell and ConfigMgr 2012

A few months ago I did a blog post about installing user-targeted applications during operating system deployments via PowerShell and ConfigMgr. This time I will do a similar post, on request, about installing computer-targeted applications during operating system deployments. Yes, I know it might be worth a discussing about why someone is still using computer-targeted deployments, but that will not be a part of this blog post.

Script

A big part of this script, and by that also this post, might look familiar, as it’s based on the previous script for user-targeted applications. Just like with that previous script I will go through all the key steps of the script. The following five steps make sure that I only get the applications that are required for the computer. Also, in case there is nothing targeted a new variable will be created to prevent the Install Application step from starting.

Step 1 – Get the container node

The first step is to get the container node of the application deployment collections. This will be used to make sure that only (device-)collections used for application deployments will be queried. This information can be retrieved in WMI in the class SMS_ObjectContainerNode. This class shows the different folders in the console and its location. The property ObjectTypeName can be used to see the type of objects in the folder. In my case, I occasionally use identical folder names. So to get the container node information that I need, I use the following code snippet:

$ContainerNodeId = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_ObjectContainerNode ` -Namespace root/SMS/site_$SiteCode ` -Filter "Name='$Container' and ` ObjectTypeName='SMS_Collection_Device'").ContainerNodeId

Step 2 – Get the collections

The second step is to get the collections within the container with a specific collection member. This information can be retrieved in WMI via the classes SMS_ObjectContainerItem and SMS_FullCollectionMembership. This first class shows the relation between an container and the objects within an container and the second class shows the different collection members and their memberships. So to get the collections within the container and with a specific collection member, I need to join these two classes. To do this, I use the following code snippet:

$CollectionIds = (Get-WmiObject -ComputerName $SiteServer ` -Namespace root/SMS/site_$SiteCode -Query "SELECT fcm.* ` FROM SMS_FullCollectionMembership fcm, ` SMS_ObjectContainerItem oci ` WHERE oci.ContainerNodeID='$ContainerNodeId' ` AND fcm.Name='$ResourceName' ` AND fcm.CollectionID=oci.InstanceKey").CollectionId

Step 3 – Get the targeted applications

The third step is to get the applications that are targeted to the filtered collections. This makes sure that only applications deployed to collections, of which the device is a member, will be filtered. This information can be found in WMI in the class SMS_ApplicationAssignment. The property OfferTypeID can be used to see if the deployment is required or available and I only want to have the required applications. So this makes that I use the following code snippet:

$ApplicationNames = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_ApplicationAssignment ` -Namespace root/SMS/site_$SiteCode ` -Filter "TargetCollectionID='$CollectionId' and ` OfferTypeID='0'").ApplicationName

Step 4 – Create the task sequence variables

The fourth step is to create task sequence variables for the applications that have to be installed during the OS deployment. For every application I create a task sequence variable named APPIdXX with the value of the application. To achieve this I use the following code snippet:

foreach ($ApplicationName in $ApplicationNames) { $Id = "{0:D2}" -f $Count $AppId = "APPId$Id" $TSEnv.Value($AppId) = $ApplicationName $Count = $Count + 1 }

Step 5 – Create an extra task sequence variable

The fifth, and last, step is to create a task sequence variable in case there are no applications targeted to the computer. This variable can be used to skip the Install application step, to prevent it from failing. As a Install application step will fail when there is a base variable configured, but there are none supplied during the task sequence. To achieve this I use the following code snippet:

else { $TSEnv.Value("SkipApplications") = "True" break }

>> The complete script is available via download here on the TechNet Galleries! <<

Usage

Now download the PowerShell script via the link above and add the PowerShell script to an old-school Package, so it will be available for a task sequence. Then create a standard Install an existing image package task sequence. Now edit the task sequence and make sure the following steps are included:

  • InstCompTargAdd a step Run PowerShell Script with the following settings:
    • Package: <NameOfPackageThatContainsTheScript>
    • Script name: <NameOfTheScript>
    • Parameters: %_SMSTSMachineName%
      • Note: The script needs more input parameters, but I usually add those parameters directly in the script as they are “static” per environment.
    • PowerShell execution policy: Bypass
  • Add a step Install Application with the following settings:
    • Select Install applications according to dynamic variable list
    • Base variable name: APPId
    • Add Condition Task Sequence Variable SkipApplications not exists

Note: The computer account running the script needs read access to ConfigMgr. So in most cases this would mean that the Domain Computers need read access to ConfigMgr. This can be achieved via the build-in role of Read-only Analyst

Running a Service Management Automation (SMA) Runbook during a task sequence in ConfigMgr 2012

It’s been a few weeks since my last blog post, but here is a new one again. This time my blog post will be about running a Service Management Automation (SMA) Runbook during a task sequence. I will show this functionality by using an example scenario of moving a computer to a different OU.  A bit more than a year ago I did something similar but then via a Orchestrator Runbook, so this time I will take it a level further. For some, maybe even most, people and companies it might be a level to far, for now, but I would like to share it anyway. As I like ConfigMgr, PowerShell and automation, I like to prefer SMA above Orchestrator. Also, SMA will become more and more commonly used.

Create the SMA Runbook (PowerShell Workflow)

Move-ComputerLet’s start with creating the SMA Runbook that will move a computer to a different OU. Like I mentioned in my previous post about using SMA Runbook with ConfigMgr, runbooks in SMA are Windows PowerShell workflows that run on Automation Worker servers. They provide the ability to automate administrative processes for managing and deploying cloud servers, or any other function that a Windows PowerShell script can perform.To configure the Move-Computer PowerShell workflow, follow the next steps:

  • Copy the following script and save it as Move-Computer.ps1.
    workflow Move-Computer { param ([String]$ComputerName, [String]$OUName) $TargetOU = Get-ADOrganizationalUnit -Filter {name -eq $OUName} $TargetComputer = Get-ADComputer $ComputerName Move-ADObject $TargetComputer.DistinguishedName ` -TargetPath $TargetOU.DistinguishedName }

  • In the Service Management Portal, navigate to AUTOMATION.
  • In the automation screen, click RUNBOOKS, click IMPORT and the IMPORT RUNBOOK –popup will show.
  • Browse to Move-Computer.ps1 and click Open, followed by clicking the .
  • Back in the automation screen, click RUNBOOKS and select Move-Computer.
  • In the move-computer screen, click AUTHOR, click DRAFT and click PUBLISH.
  • On the message Are you sure that you want to save and publish the runbook? Runbook: ‘Move-Computer’, click YES.

Create a PowerShell script (and make it available) to start the SMA Runbook

Now It’s time to take a look at the options for running a SMA Runbook during a task sequence. Luckily SMA comes with a set of cmdlets for managing SMA Runbooks. For making these cmdlets available during a task sequence there are the following options:

  1. Import the module from a network location; On a system where System Center 2012 R2 Service Management Automation PowerShell is installed, it can be found at C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Microsoft.SystemCenter.ServiceManagementAutomation.
  2. Import the module from a package; This package needs the contents of C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Microsoft.SystemCenter.ServiceManagementAutomation of a system where System Center 2012 R2 Service Management Automation PowerShell is installed.
  3. Install System Center 2012 R2 Service Management Automation PowerShell during the task sequence.

I choose to go for the second option, because that will keep my client machine as clean as possible. Now copy the following PowerShell script, save it as Start-Runbook.ps1 and add it to an old-school package (in my case the same package as the one that includes the PowerShell module for SMA), so it can be made available during a task sequence.

param ( [Parameter(Mandatory=$true)][string]$ComputerName, [Parameter(Mandatory=$true)][string]$OUName, [switch]$WaitForCompletion ) Import-Module .\Microsoft.SystemCenter.ServiceManagementAutomation.psd1 $JobId = Start-SmaRunbook -WebServiceEndpoint "https://<ServerName>" ` -Name Move-Computer -Parameters @{"ComputerName"=$ComputerName; ` "OUName"=$OUName} if ($WaitForCompletion) { $Status = (Get-SmaJob -WebServiceEndpoint "https://<ServerName>" ` -Id $JobId).JobStatus while ($Status -ne "Completed") { Start-Sleep 5 $Status = (Get-SmaJob -WebServiceEndpoint "https://<ServerName>" ` -Id $JobId).JobStatus } }

This script will first start the Move-Computer runbook and, as I like the option in the Execute Runbook task sequence step of Wait for the runbook to finish before continuing, I also added a switch to this PowerShell script to WaitForCompletion. Specifying this option with the script will put the script in a loop of checking the status of the runbook, until the status is completed.

Put the task sequence together

Now there is a package with the PowerShell script (and the SMA PowerShell module) that will start the SMA runbook to move a computer to a different OU. The last thing to do now is to create a standard Install an existing image package task sequence and to edit it to make sure the following step are included:

  • Start-RunbookAdd a step Run PowerShell Script with the following settings:
    • Package: <NameOfPackageThatContainsTheScript>
    • Script name: Start-Runbook.ps1
    • Parameters: -ComputerName %_SMSTSMachineName% –OUName <AnOUName> -WaitForCompletion
    • PowerShell execution policy: Bypass

Note: The WaitForCompletion switch is optional. Only use it when the task sequence has to wait for the SMA runbook to complete.

Install User-targeted Applications during OS Deployment via PowerShell and ConfigMgr 2012

Let’s start my first post of this great new year with another nice PowerShell script. This post will be about deploying required user targeted applications, to the device of the primary user, during OS deployment. Yes, I know the setting of Pre-deploy software to the user’s primary device, but that doesn’t give enough control. After deployment, the device has to be completely ready for use.

A bit more than a year ago I already did a post about pre-provisioning user applications during OS deployment via Orchestrator and ConfigMgr 2012. This time I wanted to make less assumptions. I also wanted to be sure that a user is a member of a collection and what the application is that is deployed to the collection. I first tried to achieve this goal by adjusting my runbook in Orchestrator and I made it work (and it still works), but to make it work I had to use all custom PowerShell activities. This made me think why I still wanted this and I couldn’t come up with something better than “because I can”. So I decided to make one PowerShell script to find the applications and to create the task sequence variables.

Script

The main part of this script is gathering data and filtering it. In short I could say this script consists of five queries and an action. The following six steps make sure that I only get the applications, that are required for the primary user of the device, to be installed during the OS deployment.

Step 1 – Get the Primary User

The first step is to get the primary user of the device that’s being deployed. That information can be retrieved in WMI in the class SMS_UserMachineRelationship. This class shows the relationship of a user with a device, even when it’s only a suggestion yet. The properties of Sources and Types can be used to see how the primary user is defined and to see if it’s a suggestion or a “real” affinity. I know that, in my case, all the device affinities are administrator defined. So to get the user name of the primary user of a device I use the following code snippet (format is <Domain>\<User>:

$PrimaryUser = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_UserMachineRelationship ` -Namespace root\SMS\Site_$SiteCode ` -Filter "ResourceName='$ResourceName'").UniqueUserName

Step 2 – Get the Container Node

The second step is to get the container node of the application deployment collections. This will be used to make sure that only collections used for application deployments will be queried. This information can be retrieved in WMI in the class SMS_ObjectContainerNode. This class shows the different folders in the console and its location. The property ObjectTypeName can be used to see the type of objects in the folder. In my case, I occasionally use identical folder names. So to get the container node information that I need, I use the following code snippet:

$ContainerNodeId = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_ObjectContainerNode ` -Namespace root/SMS/site_$SiteCode ` -Filter "Name='$Container' and ` ObjectTypeName='SMS_Collection_User'").ContainerNodeId

Step 3 – Get the Collections

The third step is to get the collections within the container. This information can be retrieved in WMI in the class SMS_ObjectContainerItem. This class shows the relation between an container and the objects within an container. So to get the collections within the container I use the following code snippet:

$InstanceKeys = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_ObjectContainerItem ` -Namespace root/SMS/site_$SiteCode ` -Filter "ContainerNodeID='$ContainerNodeId'").InstanceKey

Step 4 – Filter the Collections

The fourth step is to filter the collections on a specific collection member. This will make sure that only collections used for application deployments AND with the specific collection member will be queried later on.  This information can be found in WMI in the class SMS_FullCollectionMembership. This class shows the different collection members and their memberships. The best thing, the property SMSID shows the collection member in exactly exactly the same format as I have the primary user of the device. So to filter the collections I use the following code snippet:

$CollectionId = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_FullCollectionMembership ` -Namespace root/SMS/site_$SiteCode ` | Where-Object {$_.CollectionID -eq $InstanceKey -and ` $_.SMSID -eq $PrimaryUser}).CollectionId

Note: For an unknown reason, to me, a normal filter did not work together with the property SMSID. That’s why I had to use an where-object statement.

Step 5 – Get the targeted Applications

The fifth step is to get the applications that are targeted to the filtered collection. This makes sure that only applications deployed to collections, of which the primary user of the device is a member, will be filtered. This information can be found in WMI in the class SMS_ApplicationAssignment. The property OfferTypeID can be used to see if the deployment is required or available. I only want to have the required applications. So this makes that I use the following code snippet:

$ApplicationNames = (Get-WmiObject -ComputerName $SiteServer ` -Class SMS_ApplicationAssignment ` -Namespace root/SMS/site_$SiteCode ` -Filter "TargetCollectionID='$CollectionId' and ` OfferTypeID='0'").ApplicationName

Step 6 – Create the Task Sequence Variables

The sixth, and last step, is to create task sequence variables for the applications that have to be installed during the OS deployment. For every application I create a task sequence variable named APPIdXX with the value of the application. To achieve this I use the following code snippet:

foreach ($ApplicationName in $ApplicationNames) { $Id = "{0:D2}" -f $Count $AppId = "APPId$Id" $TSEnv.Value($AppId) = $ApplicationName $Count = $Count + 1 }

Note: In the complete script I already created a variable $Count with the value 0 and an object named $TSEnv of Microsoft.SMS.TSEnvironment.

>> The complete script is available via download here on the TechNet Galleries! <<

Usage

Now download the PowerShell script via the link above and add the PowerShell script to an old-school Package, so it will be available for a task sequence. Then create a standard Install an existing image package task sequence. Now edit the task sequence and make sure the following steps are included:

  • imageAdd a step Run PowerShell Script with the following settings:
    • Package: <NameOfPackageThatContainsTheScript>
    • Script name: <NameOfTheScript>
    • Parameters: %_SMSTSMachineName%
      • Note: The script needs more input parameters, but I usually add those parameters directly in the script as they are “static” per environment.
    • PowerShell execution policy: Bypass
  • Add a step Install Application with the following settings:
    • Select Install applications according to dynamic variable list
    • Base variable name: APPId

Note: The computer account running the script needs read access to ConfigMgr. So in most cases this would mean that the Domain Computers need read access to ConfigMgr. This can be achieved via the build-in role of Read-only Analyst.

Setting a Static IP Address during a Deployment via PowerShell and ConfigMgr 2012

This week my blog post will be about setting a static IP address during a deployment. I’m going to do this via a combination of a PowerShell script, a computer variable and a task sequence. I know it is possible in the Task Sequence Wizard to supply static IP information, but there are two reason why I did not use that solution:

  1. I’ve seen a lot of situations where the IP configuration got applied after the policy requests were done to the Management Point. This would cause the task sequence to fail.
  2. I wanted a zero touch experience for the persons performing the deployment.

PowerShell Script

Let’s start with the most important part of my solution, a PowerShell script. This script sets a static IP address with, a subnet, a gateway and two DNS servers. It needs an IP address as input and needs to be adjusted per situation, as I hardcoded my subnet, gateway and DNS servers in the call of the function. It can be easily adjusted to need more input variables for a subnet, a gateway and two DNS servers. The variable names tell the story of which number is needed when.

param ( [string]$strIPAddress ) function Set-StaticIPAddress ($strIPAddress, $strSubnet, $strGateway, $strDNSServer1, $strDNSServer2) { $NetworkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IpEnabled = 'True'" $NetworkConfig.EnableStatic($strIPAddress, $strSubnet) $NetworkConfig.SetGateways($strGateway, 1) $NetworkConfig.SetDNSServerSearchOrder(@($strDNSServer1, $strDNSServer2)) } Set-StaticIPAddress $strIPAddress "255.255.255.0" "192.168.137.1" "192.168.137.100" "192.168.137.101"

Task Sequence

SetStaIPAddNow add the PowerShell script to an old-school Package, so it will be available for a task sequence. Then create a standard Install an existing image package task sequence. Now edit the task sequence and make sure the following step is included:

  • Add a step Run PowerShell Script with the following settings:
    • Package: <NameOfPackageThatContainsStaticIPScript>
    • Script name: <NameOfTheStaticIPScript>
    • Parameters: %IPAddress%
      • Note: IPAddress is the computer variable that I use to set the IP address for a device.
    • PowerShell execution policy: Bypass

Computer Variable

CompVariJust a small note about the specified computer variable. There are multiple way’s of adding this variable. One way is creating the variable by hand via the nice sun/star-shaped button, another way is creating a small addition for my Import Computer Information Form.

Deploying Windows Embedded 8 Standard with Write Filter Enabled via ConfigMgr 2012

Its been a while since my previous blog post, so I had some time to collect information for a couple of blog posts and this is the first one! I like it when this are being done automatically. So this week I’m not going to write a PowerShell script myself, but I use a tool to generate it for me. In this blog post I will show the global steps that can be used to create a complete deployment of Windows Embedded 8 Standard with the Write Filter enabled and configured.

Create Windows Embedded 8 Standard Image

The first thing that we have to do is to create a Windows Embedded 8 Standard Image. This can be done by following the next three steps:

  1. Create a boot media with the Image Builder Wizard.
  2. In the Windows Setup of the Image Builder Wizard supply the following information.
    1. On the Windows Setup page, click Install now.
    2. On the Enter the product key to activate Windows page, enter the product key and click Next.
    3. On the License terms page, select I accept the license terms and click Next.
    4. On the Choose how to create your image page, select Use a template, select Template Device ThinClient and click Next.
    5. On the Choose a language and other preferences page, select the following and click Next.
      1. Language to install: English (United States).
      2. Time and currency format: Dutch (Netherlands).
      3. Keyboard or input method: United States-International.
    6. On the Summary of drivers and features page, click Next.
      1. (Optional) Select Modify Drivers or Modify Features to add additional drivers or features.
    7. On the Where do you want to install Windows page, select a drive and click Next.
  3. Capture the image via either a capture media or a combination of sysprep and imagex/ dism.

Take a look at the following links for the download of the Image Builder Wizard and more information:
Download Windows Embedded 8 Standard: http://www.microsoft.com/en-us/download/details.aspx?id=37019
Example about creating a custom image: http://msdn.microsoft.com/en-us/library/jj979453(v=winembedded.81).aspx

Create Write Filter Settings

The next thing that we have to do is to create the Write Filter settings. There can be a lot written about this tool, but the main thing is that it can remotely connect to a thin client, apply the Write Filter settings, and generate a PowerShell script with all the specific Write Filter settings.

Take a look at the following links for the download of the Embedded Lockdown Manager and more information:
Download Embedded Lockdown Manager: http://www.microsoft.com/en-us/download/details.aspx?id=37020
Example about creating custom settings: http://msdn.microsoft.com/en-us/library/jj980221(v=winembedded.81).aspx

Deploy Windows Embedded 8 Standard with Write Filter enabled via a Task Sequence

EnaWriFilNow the best part comes, we’re going to use the previously created image and script in a task sequence. It all starts with a standard Install an existing image package task sequence. Now edit the task sequence and make sure the following configurations are included:

  • Edit the step Apply Operating System, select Apply operating system from a captured image and select the captured image.
  • Add a step Set Task Sequence Variable with the following settings:
    • Task Sequence Variable: SMSTSPostAction
    • Value: cmd /c shutdown /r /t 60 /f
  • (Needed with HP Thin clients) Add a step Run Command Line with the following settings:
    • Command line: bcdedit /set {current} bootstatuspolicy ignoreallfailures
  • Add a step Run PowerShell Script with the following settings:
    • Package: <NameOfPackageThatContainsWriteFilterScript>
    • Script name: <NameOfTheWriteFilterScript>
    • Parameters: –ComuterName %_SMSTSMachineName%
    • PowerShell execution policy: Bypass

The most important part is the SMSTSPostAction. Setting this variable makes sure the system will restart after the task sequence is done. This is important for two reasons, one it is needed to finish the Write Filter configuration and two it is needed to make sure that the task sequence will finish successful.

Preventing initiation of available deployments on specific systems with ConfigMgr 2012

This week I want to devote a small post to a question that I read on windows-noob.com. The question came to the point whether, or not, it is possible to deploy applications via a task sequence, but only allow administrators to actually run it. This question triggered me to look a bit better into the different Client Settings and then specifically the setting of Install permissions. This setting gives us the possibility to prevent the initiation of available deployments via the Software Center and the Application Catalog on specific systems. So in this post I will show that setting by only allowing administrators to initiate available deployments.

Configuration

CompAgenInstPermNow lets start with the configuration, which is actually very easy, but like always it’s all about knowing that the possibility exists. The Install permissions –setting is another new (Computer) Client Setting under Computer Agent. This setting can be used to allow All users (default), Only administrators, Only administrators and primary users or No users to initiate available deployments on a specific system. To configure this, follow the next steps:

  • In the Configuration Manager Console navigate to Administration > Overview > Client Settings.
  • On the Home tab, in the Create group, select Create Custom Client Device Settings and the Create Custom Client Device Settings –popup will show.
  • On the General page, fill in with Name <aName> and select Computer Agent.
  • On the Computer Agent page, select next to Install permissions Only Administrators and click Ok.
  • Select the new policy <aName> and on the Home tab, in the Client Settings group, select Deploy.
  • Select <aDeviceCollection> and click Ok.

Result

After the deployment of the new Client Settings it is time to take a look at the impact on targeted system(s). Normally I’m a huge fan of looking at the client logs for the results, but in this case the log files don’t “speak” as much as the real error messages. When a normal users now logs on to the system and tries to initiate an available deployment, the following error messages will appear.

Software Center Application Portal
SoftCentInstErro PortInstErro

Deploying Windows 8 and Customizing the Lock Screen with ConfigMgr 2012

This week my post will be about the deployment of Windows 8 and then with a customized lock screen. One of the main complaints about a customized deployment of Windows 8 was that it wasn’t possible to set a customized lock screen without using unsupported methods of “hacking” file permissions and replacing the pictures. This has changed since the cumulative update of November for Windows 8 (see also here).

One of the nice adjustments with this cumulative update is that it enables enterprise customers to customize the default lock screen. This setting is introduced as a Group Policy –setting, named Force a specific default lock screen image. In this post I’m not going to use the Group Policy –setting, but only the corresponding registry value LockScreenImage under HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization. The reason for that is simple, I like setting a customized lock screen via my task sequence, because it gives a clear view when the task sequence is successfully ended.

Prerequisites

Like last week, before we can start to deploy Windows 8 we need ConfigMgr 2012 SP1. The biggest difference is that Microsoft released updated binaries, this week (see here), for ConfigMgr 2012 SP1. These binaries prevent the problems with deploying Windows 8 and installing the client. Besides that, the following two bullets are a prerequisite for this post:

  • An activated version of Windows 8 Enterprise. Without activation it’s not possible to personalize the default lock screen.
  • The cumulative update of November 2012 (KB2770917). Without this update, Windows 8 does not support customizing the default lock screen.

Configuration

TSEdiSetLocScrNow, after the prerequisites are met, let’s start with configuring the task sequence. There are only a few steps that need to be configured and they are all basic actions. So I won’t go into a lot of details, besides the batch file with the real actions. These are the global steps:

  • Add a Configuration Manager Client Package (default)
  • Add a x86/ x64 Boot Image (default)
  • Add a Operating System Image of Windows 8 (default install.wim)
  • Create an Package, with as content the new lock screen image and a batch file. The content of the batch file should look like this:

    REM ============================================================================== REM Make OEM Background directory REM ============================================================================== MD "C:\<NewLockScreenFolder>" REM ============================================================================== REM Copy OEM Background image REM ============================================================================== XCOPY "%~dp0<NewLockScreenImage>.jpg" "C:\<NewLockScreenFolder>" /HERCIY REM ============================================================================== REM Make Windows use OEM Background image REM ============================================================================== REG ADD HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization /V LockScreenImage /T REG_SZ /D C:\<NewLockScreenFolder>\<NewLockScreenImage>.jpg /F

  • Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).
    • Note: In case KB2770917 is not part of the Windows 8 image, then it is necessary to deploy it during the task sequence via an Install Updates –step.
  • Edit the new Task Sequence and add a Run Command Line –step (see picture). Now add as Command line <NameOfBatchFile>.cmd, select Package and Browse to the created Package.

Result

After all the configuring is done, it’s time to take a look at the results. In this case, I think, it’s not interesting to look at the log files, but just at the end result. So under here, on the left side is the result of a normal deployment and on the right side is the result of my custom deployment.

Default Custom
OldLockScreen NewLockScreen

Deploying Windows 8 including Optional Windows Features with ConfigMgr 2012

This week my post will be about the deployment about the deployment of Windows 8 and then including optional Windows features. I already did a post like this about Windows Server 2012, and the methods are similar, but I’m still getting, and seeing, lots of questions about how it works for Windows 8.

So what I really want to show in this post are the different options for deploying Windows 8 including some random Optional Windows Feature(s). The three most used options for this are DISM, Powershell and MDT. Well, actually, to be really correct, there is only one option to install Features in Windows 8 and that’s DISM. Both, Powershell and MDT are just different methods for calling DISM actions. In the rest of this post I will show these three methods and in all three examples I will install the same the same feature, TelnetClient. Why this feature? Well, actually just because it installs quick.

Prerequisites

Before we can start, to deploy Windows 8 we need ConfigMgr 2012 SP1, but the introduction of the RTM version of that caused serious problems with the deployment of the client on Windows 8 (also during a task sequence). Microsoft provided two solutions for this and everyone can pick the one they like the most. The most important part is that picking one of the following solutions is a prerequisite for the rest of this post:

  • Install KB2801987 on all site servers.
  • Offline service KB2756872 into the Windows 8 image.

Method 1: Dism

TSEditInstFeatDISMThe first method that I want to show, which is also the basis for the following methods, is deploying Windows 8 and optional Windows features via Dism. This can be done quickly, by performing the following global steps:

  • Add a Configuration Manager Client Package (default)
  • Add a x86/ x64 Boot Image (default)
  • Add a Operating System Image of Windows 8 (default install.wim)
  • Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).
  • Edit the new Task Sequence and add a Run Command Line –step (see picture). Now add the command line Dism.exe /Online /Enable-Feature /FeatureName:TelnetClient.

Note: To find the name of the features that we want to install, use: Dism.exe /Online /Get-Features. Also good to know, in Dism it is necessary to specify the top-level feature before we can install a sub-level feature.

Method 2: Powershell

TSEditInstFeatPHSThe second method that I want to show is deploying Windows 8 and optional Windows features via Powershell. This can be done quickly, by performing the following global steps:

  • Add a Configuration Manager Client Package (default)
  • Add a x86/ x64 Boot Image (default)
  • Add a Operating System Image of Windows 8 (default install.wim)
  • Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).
  • Edit the new Task Sequence and add a Run Command Line –step (see picture). Now add the command line Powershell.exe Install-WindowsOptionalFeature –Name TelnetClient –Online.

Note: To find the name of the features that we want to install, use: Powershell.exe Get-WindowsOptionalFeature –Online. Also good to know, in Powershell it is not necessary to specify the top-level feature before we can install a sub-level feature.

Method 3: MDT 2012 Update 1

TSEditInstFeatMDTThe third, and last, method that I want to show is deploying Windows 8 and optional Windows features via MDT 2012 Update 1. This can be done quickly, by performing the following global steps:

  • Install MDT 2012 Update 1
  • Run Configure ConfigMgr Integration
  • Add a Configuration Manager Client Package (default)
  • Add a x86/ x64 Boot Image (default)
  • Add a Operating System Image of Windows 8 (default install.wim)
  • Create a Microsoft Deployment Toolkit Package
  • Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).
  • Edit the new Task Sequence, add a Use Toolkit Package –step, add a Gather –step and add a Install Roles and Features –step. Here we can select the Operating System and the Features (see picture).

Note: To deploy .NET Framework 3.5 there are extra sources needed. Create a network share with the contents of the sources\sxs –folder from the Windows 8 –media and add a Set Task Sequence Variable –step. Set as Task Sequence Variable WindowsSource and as Value <NetworkShareWithSXSFolder>.