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 = @()


function checkService{

param (


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

 return $serviceStatus


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


 $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)


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

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



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



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



Remove-Job -State Completed

import-csv -Path ServiceStatus.csv

[PowerShell] Retrieving hard disk health through SMART status

To get the SMART status of the hard disk with PowerShell, you could run the following:

Get-WmiObject win32_diskdrive|Select-Object Status


Below is a sample script to check multiple PC’s SMART status by getting a list of PC names from a text file.

$allComputers=Get-Content -Path C:\temp\pc.txt

foreach($computer in $allComputers)

$isonline=test-connection -Quiet -count 2 -ComputerName $computer

$diskStatus= Get-WmiObject win32_diskdrive -ComputerName $computer|Select-Object -ExpandProperty Status

Write-Host -ForegroundColor Green "$computer is online and disk status is $diskStatus";
Write-Host -ForegroundColor Red "$computer is offline";


[AutoIT] Check free disk space for multiple drives.

Sometimes you may want to check for the free disk space for multiple drives, even multiple computers in your network. If you are a server guy or someone with domain admin rights, you may want something more robust such as Lansweeper, Spiceworks, Open-AudIT, Zabbix, Nagios, OCS Inventory NG or the like to do an inventory. What if you are just a desktop admin?

The traditional way is to map the drives and jot down the free space manually, but that would not work if you have a large numbers of drives to check. I wrote the following code to accomplish the task, all you have to do is create a text file with one drive letters/UNC path per line and drag and drop it to the executable (alternatively, you can pass the text file’s filename as a parameter to the executable). The result will be presented in a Excel table.

#include <Excel.au3>
If $CmdLine[0] < 1 Then
    MsgBox(0, "Error", "Please provide text file as parameter.")

$file = FileOpen($CmdLine[1], 0)

$lineNo = 1

If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")

Local $oExcel = _ExcelBookNew() ;Create new book, make it visible
If @error Then
    MsgBox(0, "Error", "Unable to create Excel instance.")

;Writing the header
_ExcelWriteCell($oExcel, "Disk", 1, 1)
_ExcelWriteCell($oExcel, "Free Space", 1, 2)
_ExcelWriteCell($oExcel, "Total Space", 1, 3)

While 1
    $line = FileReadLine($file)
    If @error = -1 Then ExitLoop

    $lineNo = $lineNo + 1

    ;Write the disk name
    _ExcelWriteCell($oExcel, $line, $lineNo, 1)
    ;Write the disk free space
    _ExcelWriteCell($oExcel, (Round( (DriveSpaceFree($line)/1024 ),2) &" GB"), $lineNo, 2 )
    ;Write the total disk space
    _ExcelWriteCell($oExcel, (Round( (DriveSpaceTotal($line)/1024 ),2) &" GB"), $lineNo, 3 )



The compiled executable including source file and project file for ISN AutoIT Studio can be downloaded here.

Feel free to download drivespace.zip from the link above.

For simplicity, not much error checking had been implemented and the code is provided as is.


WMI Explorer for those who are interest in WMI programming

For those of you who are interest in WMI programming, tools like WMI code Creator and Scriptomatic can be useful. The command wbemtest might come in handy sometimes as well but I find that WMI Explorers are more useful when you would like to know what classes are avaiable and when you would like to run and see what results does the Query produces.

I find the following three WMI Explorer to be very useful:

Happy programming 🙂