Hi. My name is Jesse, and I’m a script-aholic.
I also enjoy sleep, which is typically what motivates me to automate many processes using Powershell. Assuming that you enjoy sleeping as much as I do, I’ll gladly share with you a recent script that I wrote.
Backstory:
I was tasked to deploy an application via ConfigMgr to a group of VPN users around the world. Timing was of the essence, and I needed to ensure that the clients received policy as soon as they were available. However, as the users were global and it was uncertain as to exactly when they would be checking in, I needed to devise a way to detect network connectivity and trigger the machine policy evaluation and retrieval, even as it occurred overnight.
After grouping the machines into a collection in which the application was deployed, I decided to write the following script to automate the policy retrieval. The script does the following:
- Imports the ConfigMgr module and changes to the site directory
- Grabs all of the machine names in the defined collection
- Grabs a count of machines in the collection
- Starts a do-while loop that continues until $i equals the total count of the collection
- For each machine, it tries to connect once
- If successful
- Triggers the Machine Policy Evaluation and Retrieval
- Removes the machine from the $Machines variable list (not the collection) so as to not continuously check the same successful machine
- Increments the value of $i for the do-while loop
- Writes the machine name and time of successful connectivity to .\MachineEvalTrigger.txt
- If failed connectivity
- Will continuously try each member of the $Machines variable until $i reaches the count of machines in the variable
- If successful
There is a mandatory parameter, so the syntax is:
.\Trigger-MachinePolicyEval.ps1 –CollectionName <CollectionName>
The script is below. Now, catch up on some beauty sleep!
<# Name: Trigger-MachinePolicyEval.ps1 Author: Jesse Walter Date: 02/25/2015 #> [CmdletBinding()] param( [Parameter(Mandatory=$True)] [string]$CollectionName ) Function Import-CMModule { $Drives = Get-PSDrive -PSProvider FileSystem | Where-Object -Property Free $FreeDrives = $Drives.root $CMLets = "configurationmanager.psd1" if (Test-Path -Path "c:\program files (x86)\Microsoft Configuration Manager\AdminConsole\bin\configurationmanager.psd1") { Write-Host "Importing from C:" Import-Module "c:\program files (x86)\Microsoft Configuration Manager\AdminConsole\bin\configurationmanager.psd1" } else{ ForEach ($drive in $FreeDrives) { Write-Host "Attempting to locate CMLets on $drive..." -ForegroundColor Yellow cd $drive $FilePath = (gci $drive -File -Filter $CMLets -Recurse -Force -ErrorVariable FailedItems -ErrorAction SilentlyContinue).FullName if ($FilePath) { $CMModule = $FilePath Write-Host "Found $CMModule. Importing..." -ForegroundColor Green try{ Import-Module $CMModule } catch { $_ } break } else { Write-Host "Cannot find in $drive..." -ForegroundColor Red } } } } Import-CMModule $site = (gwmi -ComputerName $env:COMPUTERNAME -Namespace "root\SMS" -Class "SMS_ProviderLocation").SiteCode $sitecodeDir = $site + ":" CD $sitecodeDir $Machines = (Get-CMDevice -CollectionName $CollectionName).name $i = 0 do { ForEach ($machine in $Machines){ if (Test-Connection -ComputerName $machine -Count 1 -Quiet) { $trigger = "{00000000-0000-0000-0000-000000000021}" $time = (Get-Date).DateTime $Machines = $Machines | ?{$_ -ne $machine} $i++ Invoke-WmiMethod -ComputerName $machine -Namespace root\ccm -Class sms_client -Name TriggerSchedule $trigger Write-Host $machine "is connected" -ForegroundColor Green Add-Content -Value "$machine $time" -Path .\MachineEvalTrigger.txt } else {Write-Host $machine "not reachable" -ForegroundColor Yellow} } } while ($i -le $Machines.count)