troubleshooting Question

Powershell Script - Increment Counter?

Avatar of Ron Shorts
Ron ShortsFlag for United States of America asked on
PowershellVB ScriptSCCMScripting Languages
12 Comments1 Solution141 ViewsLast Modified:
Hi Experts,

Looking for some expertise with this script.

Here is what the script does:

1) Reads from a text file with computer names and remotely runs a SCCM advertisement.

2) The advertisement opens some processes - which I have in a loop in this script.  

3) When the processes read 0 the loop is completed, then moves to the next command to RESTART the computer.

4) Is there any way to have this run 3 times, and then shutdown on the 3rd time?

$OutArray = @()
workflow foreachrerun {
    foreach –parallel ($computer in $computers) {
       InlineScript {
Function Start-CCMRerunAdvertisement {
        [Parameter(Mandatory=$false)][string]$advertisementId = "*",
        [Parameter(Mandatory=$false)][string]$packageId = "*",
        [Parameter(Mandatory=$false)][int]$maxRun = 1
        #[Parameters(Mandatory=$false)][switch]$moreThanPing = $false
    if($advertisementId -eq "*" -and $packageId -eq "*") {
        Write-Error "You must supply either an AdvertisementID or a PackageID"
        return "Missing Parameters"
    $searchString = "$advertisementId-$packageId-*" 
    if(!(Test-Connection -ComputerName $computername -ErrorAction SilentlyContinue)) {
        if($moreThanPing) { 
            if(!(Get-ChildItem "\\$computername\c$" -ErrorAction SilentlyContinue)) {
                Write-Error "System Offline"
                Return "System Offline"
        } else {
            Return "$Computername is Offline"
    Write-Verbose "Getting ID of ScheduleMessage on $computername"
    $schMsgs = Get-WmiObject -ComputerName $computername -Namespace "root\ccm\policy\machine\actualconfig" -Class CCM_Scheduler_ScheduledMessage
    $thisMsg = $schMsgs | ? { $_.ScheduledMessageID -like $searchString } | Sort ActiveTime -Descending | select -First $maxRun
    if(!$thisMsg) {
        Write-Verbose "Cannot Find Advertisement/Package on Target Computer"
        Return "Cannot Find Advertisment"
    $thisMsg | % {
        [xml]$activeMessage = $_.activeMessage
        $amProgramId = $activeMessage.SoftwareDeploymentMessage.ProgramID
        $amAdvId = $activeMessage.SoftwareDeploymentMessage.AdvertisementID
        $amPkgId = $activeMessage.SoftwareDeploymentMessage.PackageID
        $ScheduledMessageId = $_.ScheduledMessageId
        Write-Verbose  "Restarting $amArogramId (ADV=$amAdvId) (PKG=$amPkgId) for Schedule Message $ScheduledMessageId"
        $softwareDist = Get-WmiObject -ComputerName $computername -Namespace "root\ccm\policy\machine\actualconfig" -Class CCM_SoftwareDistribution -Filter "ADV_AdvertisementID = '$amAdvId' and PKG_PackageID = '$amPkgId'"
        $original_Rerun = $softwareDist.ADV_RepeatRunBehavior
        if($original_Rerun -ne "RerunAlways") {
            write-verbose "Changing Rerun Status from $original_Rerun to RerunAlways"
            $softwareDist.ADV_RepeatRunBehavior = "RerunAlways"
            $softwareDist.put() | Out-Null
        Write-Verbose "Triggering Schedule on $computername"
        Invoke-WmiMethod -ComputerName $computername -Namespace "root\ccm" -Class "SMS_CLIENT" -Name TriggerSchedule $ScheduledMessageId | Out-Null
        Write-Verbose "Sleeping for 5 seconds"
        Start-Sleep -Seconds 5
        if($original_Rerun -ne "RerunAlways") {
            Write-Verbose "Changing Rerun Status back to $original_Rerun"
            $softwareDist.ADV_RepeatRunBehavior = "$original_Rerun"
            $softwareDist.put() | Out-Null
        Return "Advert Reran on succesfully on $computername"
function Send-EmailOffline {
    Send-MailMessage -From “" -To "" -SMTPServer -Subject “$($computername) is Offline" -Body "$($ComputerName) is Offline, please power on and re-run script."
function Send-EmailKickit {
    Send-MailMessage -From “" -To "" -SMTPServer -Subject “$($computername) Completed." -Body "$($ComputerName) Completed and is rebooting."
function Test-MyConnection {
    param (
    if (Test-Connection $computername -Quiet -Count 2) {
        Write-Output "Ping successful on $($computerName)"      
        Test-Running -ComputerName $ComputerName 
    else {
        Send-EmailOffline -ComputerName $computername   
function Test-Running {
    param (
$processList = @'
    "Name",             "Expected",     "Running"
    "cmd",              "1",            "0"
    "TrustedInstaller", "1",            "0"
    "TIWorker",         "1",            "0"
    "OfficeClickToRun", "2",            "0"
'@ | ConvertFrom-Csv | ForEach-Object {$_.Expected = [int]$_.Expected; $_}
    $splat = @{}
    $splat['ComputerName'] = $computerName
    #Write-Output "Monitoring processes on $($computerName)" 
    Do  {
      $processList | ForEach-Object {
          $_.Running = @(Get-Process $_.Name @splat -ErrorAction SilentlyContinue).Count
      ($processList | Format-Table -AutoSize | Out-String).Split("`r`n", [StringSplitOptions]::RemoveEmptyEntries) | Write-Output
      If ($running = @($processList | Where-Object {$_.Running -ge $_.Expected}).Count) {
          Start-Sleep -Seconds 5
      Write-Output "Monitoring processes on $($computerName)" 
    } Until (-not $running)
    Send-EmailKickit -ComputerName $computername 
    $Today = (Get-Date).ToString('MM-dd-yyyy'),
    $ExactTime = Get-Date -Format "MM-dd-yyyy HHmm tt"
    $Logfile = "c:\input\Log.csv"
    $myobj = "" | Select "Computer", "ExactTime"
    $myobj.Computer = $ComputerName
    $myobj.ExactTime = $($(Get-Date).ToString('yyyy-MM-dd::hh:mm:ss'))

    $OutArray += $myobj
    $OutArray | Export-Csv $Logfile -NoTypeInformation -Append 
    Return "Process count finished on $computername"

# force reboot, after all process requirements met
Restart-Computer -Computer $Computername -Force

            Start-CCMRerunAdvertisement –ComputerName $using:Computer -AdvertisementID "TMC73737" 
            Test-MyConnection -ComputerName $using:Computer
$ComputerList  = Get-Content "c:\input\computerlist.txt"
foreachrerun -Computers $ComputerList
Darrell Porter
Enterprise Business Process Architect

Our community of experts have been thoroughly vetted for their expertise and industry experience.

Join our community to see this answer!
Unlock 1 Answer and 12 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 12 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros