The awesome world of child task sequences

Like last week I’m staying in the world of new features of Configuration Manager, version 1710. This time it’s all about the awesome world of child task sequences. Awesome. To be a bit more specific, the awesome world of child task sequences, which refers to the newly introduced task sequence step Run Task Sequence. This opens up a whole lot of options, from using specific standards throughout all deployments until enabling different administrators from maintaining their own child task sequence. In this post I’ll go through a short introduction about the Run Task Sequence step, followed by the configuration options for the Run Task Sequence step. I’ll end this post with the end result of running a child task sequence, by showing how it’s logged.

Introduction

Starting with Configuration Manager, version 1710, it’s possible to add a new task sequence step that runs another task sequence. That is the Run Task Sequence step. This creates a parent-child relationship between the task sequences. Child task sequences are enablers for creating modular and re-usable task sequences. Before starting with using child task sequences, make sure to be familiar with the following:

  • The parent and child task sequences are combined into a single policy;
  • The task sequence environment is global;
  • The status messages are sent for a single task sequence operation;
  • The child task sequence writes entries to the same smsts.log file (like a group);

Note: Make sure to go through the information mentioned in the More information section, as the second link provides useful information about the abilities.

Configuration

Now let’s have a look at the available configuration options for using the Run Task Sequence step. The four steps below walk through those configuration options. After that, the parent task sequence can be deployed like any other task sequence. However, when deploying a parent task sequence, be aware that the criteria for showing the “high-impact” warning is not detected in Software Center when the child task sequence contains the “high-impact” steps. In that case, use the User Notification properties of the parent task sequence to force the “high-impact” warning.

1 Open the Configuration Manager administration console and navigate to Software Library > Overview > Operating Systems > Task Sequences;
2 Now either create a new task sequence by using Home > Create > Create Task Sequence, or select an existing task sequence and select Home > Task Sequence > Edit to open the Task Sequence Editor;
3 In the Task Sequence Editor, select Add > General > Run Task Sequence;
4

TS_RunTaskSequenceIn the Run Task Sequence step, it’s as simple as browsing to the task sequence and selecting it.

Note: It’s not possible to select a task sequence that contains a boot image reference. The boot image reference has to be on the parent task sequence.

Note: Keep in mind that any chain containing a disabled task sequence will fail and that the Continue on error won’t work for that step containing the disabled task sequence.

Result

Let’s end this post by having a look at the end result. I’ll do that by looking at the smsts.log file and by looking at the deployment status in the Configuration Manager administrator console. When looking at the deployment status, see screenshot below, the first section shows the start of the parent task sequence and the second section shows the start of the child task sequence, like a group within a normal task sequence.

TS_StatusMessage

When looking at the smsts.log, something similar is shown, see screenshot below. The start of the child task sequence is shown like the start of a group within the parent task sequence.

TS_SMSTSLOG

More information

For more information about the Run Task Sequence step, please refer to the following articles:

Download package content during a task sequence

This week a blog post about one of the smaller new features of ConfigMgr 1511 and later. I want to devote this post to the new ability to easily download the content of a package during a task sequence. This ability is mainly introduced to work with the Windows 10 upgrade scenarios and the WinPE peer cache functionality. However, it can also be used to replace all the Run Command Line task sequence steps that were used to copy the content of normal Packages during a task sequence. In this post I’ll go through the different configuration options of that new ability, the Download Package Content task sequence step. I will also show an example in a task sequence and I will end with a look at the results in the smsts.log.

Configuration options

The Download Package Content task sequence step can download the content of Boot Images, Operating System Images, Operating System Upgrade Packages, Driver Packages and Packages. It also has the very nice option of Save path as variable, which can be used to easily store the location of the downloaded package content. When a variable is configured it has to be referred to in subsequence steps with a numerical suffix. That means that when ContentPath is used, as variable, it has to be referred to like ContentPath01. The order in the list determines the numerical suffix that’s used as reference.

Task Sequence working directory

The download location Task sequence working directory can be used at any moment after the Format and Partition Disk task sequence step. After that step the content will be kept and moved during the running time of the task sequence. The variable configured with Save path as variable will be updated when the location of the downloaded content has changed.

Configuration Manager client cache

The download location Configuration Manager client cache can be used at any moment after the Setup Windows and ConfigMgr task sequence step. When the ConfigMgr client is up-and-running, the content can be downloaded to its cache. The content will be available even after the task sequence is finished. This allows the client to act as a peer cache source for other peer cache clients. The variable configured with Save path as variable will be updated when the location of the downloaded content has changed.

Custom path

The download location Custom path can be used at any moment in the task sequence. However, keep in mind that the content will not be moved during the running time of the task sequence. Only the changes to the driver letter, due to reboots, will be updated in the variable configured with the Save path as variable. The content itself will be left untouched. When this option is used after the Setup Windows and ConfigMgr task sequence step, the content will be available after the task sequence is finished.

Task Sequence example

Now that the configuration options are clear, let’s go through a configuration example. That example will mainly show how to use the configured variable.

1 DownloadPackageContentThe first action is to download the content and to configure the download-to location. This can be achieved by selecting a number of packages, of the previously mentioned types, and by specifying the download-to location. To make accessing the content easier, select Sava path as a variable and use ContentPath as variable.
2 DownloadPackageUsageThe second action is to use the content after it is downloaded. This can be achieved by using a Run Command Line step and using the ContentPath02 variable. That will refer to the downloaded content of the Set Image Version Package. Now simply refer to anything available within that Package.

Important: After saving the task sequence by clicking OK or Apply the list with packages will be rearranged by the letters of the alphabet. This will impact the numerical suffix that is needed to point to the right location. My advise is to save the task sequence before referring to the content.

Result

After going through all the configuration options and the task sequence example, it’s time to look at some results. Let’s have a look at how the first Package is handled by the OSDDownloadContent component, in the smsts.log, for the three different download locations.

Task sequence working directory

The download location Task sequence working directory is the easiest to handle for the task sequence. The task sequence will download the content to the C:\_SMSTaskSequence\Packages directory and set the ContentPath01 variable to the location of the first Package. After that it will add the ContentPath01 variable to the list of paths that need to be remapped on reboot.

petervanderwoude.nl

Configuration Manager client cache

The download location Configuration Manager client cache requires a few additional actions. The task sequence will download the content to the C:\_SMSTaskSequence\Packages directory. After that it will stage the downloaded content to the client cache directory and set the ContentPath01 variable to the location of the first Package in the client cache. After that it will add the ContentPath01 variable to the list of paths that need to be remapped on reboot.

SMSTS_CCMCache

Custom path

The download location Custom path requires similar additional actions. The task sequence will download the content to the C:\_SMSTaskSequence\Packages directory. After that it will stage the downloaded content to, in this case, the C:\Temp folder and set the ContentPath01 variable to the location of the first Package in that folder. After that it will add the ContentPath01 variable to the list of paths that need to be remapped on reboot.

SMSTS_CTemp

More information

For more information about this new task sequence step, please refer to the following article: https://technet.microsoft.com/en-us/library/mt629396.aspx#BKMK_DownloadPackageContent

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