Dell Kace

[POWERSHELL] CHECK QUEST KACE ONE AGENT SERVICE FOR MULTIPLE COMPUTER (VERSION #4)

Here is the #4 version, changes as below:

  • Limit concurrent running background job with¬†$maxConcurrentJobs to 50
  • use Start-Job to check online status as well as check service

 

#The OU to search
 $SearchBase = "OU=COMPUTER,OU=World_First,DC=domain,DC=local"

#Search result of computers (Windows only)
$Computers = Get-ADComputer -Filter {OperatingSystem -Like "Windows*"} -SearchBase $SearchBase -SearchScope Subtree -ErrorAction Stop -ErrorVariable NoComputers|sort Name
if($noComputers){
 Write-Warning -Message "Unable to get computer from AD"
 Exit
}

$ServiceStatusFile = "ServiceStatus.csv"
$OfflineFile = "Offline.csv"
$noServiceFile = "noService.csv"
$maxConcurrentJobs = 50 #Max. number of simultaneously running jobs

#Array for online computers
$onlineComputers = @()
#Array for offline computers
$offlineComputers = @()

$ping={

function ping{
 param (
 [parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [string]$client
 )
 
 
 #win32_PingStatus variables
 $timeout= 1500
 $filter='Address="{0}" and Timeout={1}' -f $client, $timeout
 
 
 
 
 return Get-WmiObject Win32_PingStatus -Filter $filter
 
 
 
 }

}




$func={

function checkService{

param (
 [parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [string]$client
 )
 
 try{

$serviceStatus=get-service -DisplayName "Quest KACE One Agent" -ComputerName $client -ErrorAction SilentlyContinue -ErrorVariable ServiceNotAvailable|select-object MachineName,DisplayName,Status
 
 if($serviceStatus){
 $output = $serviceStatus
 return $serviceStatus
 }

else{
 
 write-warning -Message "$client,$ServiceNotAvailable"
 $output = $client +"," + $ServiceNotAvailable
 return $output
 }
 
 }
 
 Catch [System.Management.Automation.CmdletInvocationException]{
 
 write-warning -Message "$client,$ServiceNotAvailable"
 $output = $client +"," + $ServiceNotAvailable.Message
 return $output
 }
 
 Catch{
 $ErrorMessage = $_.Exception.Message
 $FailedItem = $_.Exception.ItemName
 }
 
 } 
} 
 
#Ping all computers
foreach($computer in $computers) {
 $client = $computer.Name 
 Write-Progress -Activity "Checking computer availablilty....." -status "Ping $client" -percentComplete ($computers.IndexOf($computer) / $Computers.count*100)
 if ((Get-Job -State 'Running').Count -lt $maxConcurrentJobs) {
 Start-Job -ScriptBlock {ping $args[0]} -ArgumentList @($client) -Name "$client" -InitializationScript $ping
 }else{
 Start-Sleep -Seconds 3
 Start-Job -ScriptBlock {ping $args[0]} -ArgumentList @($client) -Name "$client" -InitializationScript $ping
 }
}

#Wait for job to complete
Get-Job|Wait-Job

#Get result of ping
foreach($computer in $computers) {
 
 $client = $computer.Name
 Write-Progress -Activity "Retrieving results of availability....." -status "Ping result for $client" -percentComplete ($computers.IndexOf($computer) / $Computers.count*100)
 $pingStatus=Receive-Job -Name $client
 #Removes the ping job when result is retrieved
 Remove-Job -Name $client

#If PC is online
 if($pingStatus.StatusCode -eq '0'){
 
 $onlineComputers= $onlineComputers+($computer)
 #Create a checkService job for online PC
 if ((Get-Job -State 'Running').Count -lt $maxConcurrentJobs) {
 Start-Job -ScriptBlock {checkService $args[0]} -ArgumentList @($computer.Name) -Name "$client" -InitializationScript $func 
 }
 else{
 Start-Sleep -Seconds 5
 Start-Job -ScriptBlock {checkService $args[0]} -ArgumentList @($computer.Name) -Name "$client" -InitializationScript $func 
 }
 }
 else{
 $offlineComputers= $offlineComputers+($computer)
 Write-Warning -Message "$client is offline"
 
 $client|Out-File -FilePath $OfflineFile -Append
 
 }
}

#Wait for job to complete
Get-Job|Wait-Job

#Get result from checkService
foreach($onlinecomputer in $onlineComputers) {
 $result=receive-job -Name $onlineComputer.Name -Keep
 
 Write-Progress -Activity "Retrieving results of availability....." -status "Service result for $onlineComputer.Name" -percentComplete ($onlineComputers.IndexOf($onlinecomputer) / $onlineComputers.count*100)
 #Contains MachineName, service available
 if([bool]($result.PSobject.Properties.name -match "MachineName")){
 
 
 $result|select-object MachineName,DisplayName,Status |export-csv -Path $ServiceStatusFile -NoTypeInformation -Append
 
 }
 
 else{
 
 $result|Out-File -FilePath $noServiceFile -Append
 
 }

}
#Remove all completed job
Remove-Job -State Completed

Import-Csv $ServiceStatusFile|ft -AutoSize
Advertisements

[POWERSHELL] CHECK QUEST KACE ONE AGENT SERVICE FOR MULTIPLE COMPUTER (VERSION #3)

Here is the #3 version, changes as below:

  • use of Win32_PingStatus for a ping timeout of 1500ms because Test-Connection defaults to 4 seconds and there is no option to change that.
  • Added error handling with try/catch
  • use Start-Job to start checking for service status once found PC is online.

 

#The OU to search
 $SearchBase = "OU=COMPUTER,OU=World_First,DC=domain,DC=local"

#output files
 $ServiceStatusFile = "ServiceStatus.csv"
 $OfflineFile = "Offline.csv"
 $noServiceFile = "noService.csv"

#Search result of computers (Windows only)
 $Computers = Get-ADComputer -Filter {OperatingSystem -Like "Windows*"} -SearchBase $SearchBase -SearchScope Subtree|sort Name

#Array for online computers
 $onlineComputers = @()

#Array for offline computers
 $offlineComputers = @()

$func={

function checkService{

param (
 [parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [string]$client
 )

try{

$serviceStatus=get-service -DisplayName "Quest KACE One Agent" -ComputerName $client -ErrorAction SilentlyContinue -ErrorVariable ServiceNotAvailable|select-object MachineName,DisplayName,Status

if($serviceStatus){
 return $serviceStatus
 }

else{

write-warning -Message "$client,$ServiceNotAvailable"
 $output = $client +"," + $ServiceNotAvailable
 return $output
 }

}
 Catch [System.Management.Automation.CmdletInvocationException]{

write-warning -Message "$client,$ServiceNotAvailable"
 $output = $client +"," + $ServiceNotAvailable.Message
 return $output

}

Catch{
 $ErrorMessage = $_.Exception.Message
 $FailedItem = $_.Exception.ItemName

}

}
 }




#Check if computers are online
 foreach($computer in $computers) {

$client = $computer.Name
 #win32_PingStatus variables
 $filter='Address="{0}" and Timeout={1}' -f $client, $timeout
 $timeout= 1500
 Write-Progress -Activity "Checking computer availablilty....." -status "Ping computer $client" -percentComplete ($computers.IndexOf($computer) / $Computers.count*100)

if((Get-WmiObject Win32_PingStatus -Filter $filter).StatusCode -eq '0'){
 Start-Job -ScriptBlock {checkService $args[0]} -ArgumentList @($client) -Name "$client" -InitializationScript $func
 $onlineComputers= $onlineComputers+($computer)

}
 else{

$offlineComputers= $offlineComputers+($computer)
 Write-Warning -Message "$client is offline"

$client|Out-File -FilePath $OfflineFile -Append
 }

}







Get-Job|Wait-Job

foreach($onlineComputer in $onlineComputers){




$result=receive-job -Name $onlineComputer.Name -Keep

#Contains MachineName, service available
 if([bool]($result.PSobject.Properties.name -match "MachineName")){
 $result|select-object MachineName,DisplayName,Status|export-csv -Path $ServiceStatusFile -NoTypeInformation -Append

}

else{

$result|Out-File -FilePath $noServiceFile -Append

}

}

Remove-Job -State Completed

import-csv -Path ServiceStatus.csv