OSD collection script – PowerShell
Task sequence script which adds a computer to SoftwareCentral application deployment collections. It also removes a computer from one or more predefined OSD deployment collections. The script can be triggered by a Status Filter Rule in SCCM or as a “Run command line” step in an OSD task sequence.
Method 1: OSD task sequence
Create a “Run command line” task sequence step with the following command line:
1 |
powershell.exe -executionpolicy bypass -file ComputerCollections.ps1 -SiteServer <yoursiteserver> -SiteCode <yoursitecode> -CollectionID <yourOSDcollection> |
Use a package which contains the ComputerCollections.ps1 script (described below)
The step must be run as an account which has sufficient permissions.
Method 2: Status filter rule
Configure the Status Filter Rule as shown below.
Program:
1 |
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass -file "D:\Scripts\OSDCollectionScript.ps1" -SiteServer <SCCM server name> -SiteCode <SCCM site code> -CollectionID <OSD collection ID> -ComputerName %msgsys |
As -CollectionID you can supply one or more collection IDs separated by comma.
The PowerShell script used for both methods (ComputerCollections.ps1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
Param ( # Type in the Site Server Name [Parameter(Mandatory=$true,HelpMessage="Please enter the Site Servername", ValueFromPipelineByPropertyName=$true, Position=0)] $SiteServer, # Type in Site Code [Parameter(Mandatory=$true,HelpMessage="Please enter the Site Code", ValueFromPipelineByPropertyName=$true, Position=0)] $SiteCode, # Type in collection ID [Parameter(Mandatory=$true,HelpMessage="Please enter the CollectionID", ValueFromPipelineByPropertyName=$true, Position=0)] $CollectionID, # Type in computername [Parameter(Mandatory=$false,HelpMessage="Please enter the ComputerName", ValueFromPipelineByPropertyName=$true, Position=0)] $ComputerName = $env:COMPUTERNAME ) #Define log file name and location $LogPath = "C:\MyLogs" $LogFileName = "$ComputerName.log" $LogFile = "$LogPath\$LogFileName" #Initialize log file location if (!(Test-Path $LogPath)) { try { New-Item $LogPath -type directory -ErrorAction Stop | Out-Null } catch { $LogFile = "c:\Windows\Temp\$LogFileName" LogWrite "Log folder could not be created in chosen location. Log saved to c:\Windows\Temp instead." LogWrite ("$_.Exception.Message") } } function LogWrite([string]$LogString) { try { Add-content $script:LogFile -value "$(Get-Date -Format yyyy-MM-dd_HH:mm:ss) $LogString" -force -ErrorAction Stop } catch { #Write-Warning $_.Exception.Message } } LogWrite("### START OF SCRIPT ###") LogWrite("Running CollectionMembershipRulesNew.ps1 -SiteServer $SiteServer -SiteCode $SiteCode -CollectionID $CollectionID -ComputerName $ComputerName (running as $env:username)") #Remove the PC from the deployment collection(s) foreach($ColID in $CollectionID.Split(",")){ $DeployCollection = Get-WmiObject -ComputerName $SiteServer -Namespace "root\SMS\Site_$SiteCode" -Query "select * from SMS_Collection Where SMS_Collection.CollectionID='$ColID'" if ($DeployCollection) { $DeployCollection.Get() $DeployCollectionName = $DeployCollection.Name LogWrite("Trying to remove $ComputerName from the deployment collection `"$DeployCollectionName`" ($ColID)") $ValidDeployCollectionRules = @($DeployCollection.CollectionRules | Where {$_.RuleName -eq $ComputerName}) if ($ValidDeployCollectionRules.length -gt 0) { ForEach ($ValidDeployCollectionRule in $ValidDeployCollectionRules) { try { $DeployCollection.DeleteMemberShipRule($ValidDeployCollectionRule) | Out-Null LogWrite("Successfully removed the PC from the deployment collection `"$DeployCollectionName`" ($ColID)") } catch { LogWrite("Failed to remove the PC from the deployment collection `"$DeployCollectionName`" ($ColID)") LogWrite("$_.Exception.Message") } } } else { LogWrite("$ComputerName is not in the deployment collection `"$DeployCollectionName`" ($ColID)") } } else { LogWrite("Error in the script parameters. The deployment collection $ColID doesn't exist") } } #Add the PC to application deployment collections $TsApplicationBaseVariable = "LAB_ApplicationBaseVariable" $ComputerObjects = @(Get-WmiObject -ComputerName $SiteServer -namespace “root\sms\site_$siteCode” -class “sms_r_system” -Filter "Name = '$computerName' ") foreach ($ComputerObject in $ComputerObjects) { $resourceIds = @($ComputerObject.ResourceId) foreach ($resourceId in $resourceIds) { $resourceIDString = $resourceId.ToString() LogWrite ("Found this resource ID: $resourceIDString for $ComputerName") if ($resourceIDString.length -eq 8) { $ValidResourceID = $resourceIDString LogWrite ("The valid ResourceID is set to $ValidResourceID for $ComputerName") } } } LogWrite ("Using this resource ID to detect machine variables for $ComputerName : $ValidResourceID") $objMachineSettings = Get-WmiObject -ComputerName $SiteServer -namespace “root\sms\site_$siteCode” -class “sms_machinesettings” -Filter "ResourceID = '$ValidResourceID' " $objMachineSettings.get() Start-sleep -Seconds 5 $objMachineVariables = @($objMachineSettings.MachineVariables | where{$_.Name -match $TsApplicationBaseVariable}) $appNames = @($objMachineVariables.Value) foreach ($applicationName in $appNames) {LogWrite ("Found this application in machine variables: $applicationName for $ComputerName")} LogWrite ("Starting to add $ComputerName to relevant Software Central device install collections") #LogWrite ("I waited 10 seconds") if (($appNames -eq $null) -or ($appNames.Length -eq 0)) {LogWrite ("No applications were found in machine variables for $ComputerName")} foreach ($appName in $appNames) { #LogWrite("STEP 01") #Write-Host $appName $smsApp = Get-WmiObject -ComputerName $SiteServer -namespace “root\sms\site_$siteCode” -class “SMS_Application” -Filter "LocalizedDisplayName = '$appName' and LocalizedDescription = 'Created by SoftwareCentral' " #LogWrite("STEP 02") if ($smsApp -ne $null) { #LogWrite("STEP 03") $smsAppAssignments = @(Get-WmiObject -ComputerName $SiteServer -namespace “root\sms\site_$siteCode” -class “SMS_ApplicationAssignment” -Filter "AppModelID = '$($smsApp.ModelID[0])' and OfferTypeID = '0' and AssignmentType = '2' " ) #LogWrite("STEP 04") if ($smsAppAssignments.Length -gt 0) { #LogWrite("STEP 05") foreach ($smsAppAssignmentID in $smsAppAssignments.TargetCollectionID) { #LogWrite("STEP 06") $Collection = Get-WmiObject -ComputerName $SiteServer -namespace “root\sms\site_$siteCode” -class “SMS_Collection” -Filter "CollectionID = '$smsAppAssignmentID' and CollectionType = '2' and Name LIKE '%-install%' " #LogWrite("STEP 07") if ($Collection -ne $null) { #LogWrite("STEP 08") LogWrite("Trying to add $ComputerName to collection: $($Collection.Name)") #LogWrite("STEP 09") $Collection.Get() | Out-Null #LogWrite("STEP 10") #$ValidCollections = ($Collection | Where {$_.CollectionRules.RuleName -eq "$ComputerName"}) if (($Collection | Where {$_.CollectionRules.RuleName -eq "$ComputerName"}) -eq $null) { #LogWrite("STEP 11") try { #LogWrite("STEP 12") $NewRule = ([WMIClass]"\\$SiteServer\root\SMS\Site_$($SiteCode):SMS_CollectionRuleDirect").CreateInstance() $NewRule.ResourceClassName = "SMS_R_System" $NewRule.ResourceID = $ValidResourceID $NewRule.Rulename = $ComputerName $Collection.AddMemberShipRule($NewRule) | Out-Null LogWrite("Successfully added $ComputerName to collection: $($Collection.Name)") } catch { LogWrite("Failed to add $ComputerName to collection: $($Collection.Name)") LogWrite("$_.Exception.Message") } } else { LogWrite("$ComputerName is already a member of collection: $($Collection.Name)") } } else { #LogWrite("No valid device collection exists for installation of the application: $appName)") } } } else { LogWrite("No valid required deployments exist for application: $appName") } } else { LogWrite("No valid Software Central applications exist with the name: $appName") } } LogWrite("### END OF SCRIPT ###") |
Parameters used in the script and possible values:
AssignmentType parameter (SInt32)
Type of assignment. Possible values are:
0 CIA_TYPE_DCM_BASELINE
1 CIA_TYPE_UPDATES
2 CIA_TYPE_APPLICATION
5 CIA_TYPE_UPDATE_GROUP
8 CIA_TYPE_POLICY
OfferTypeID parameter (SInt32)
Type of offer. Possible values are:
0 REQUIRED
2 AVAILABLE
CollectionType parameter (UInt32)
Count of collection variables.
0 OTHER
1 USER
2 DEVICE