Multi-Thread Super-Fast Software Inventory Scan using WSMan (PowerShell Remoting)

Recently I was asked to pull the software inventory report from multiple severs hosted in Azure, but unfortunately pulling data from WMI not allowed, only PS Remoting was enabled, so I made some changes on my previous script and used Invoke-command to pull the date for all the servers. It was easy and the most effective way to extract that report and only took 5 minute to get the data. 🙂

Here is the modified script, I hope you might find this useful

powershellWSMan(PSRemoting).ps1
$Credential = Get-Credential
Clear-Host
$ExportFileLocation = "$env:userprofile\desktop\InvTory.csv"  
$Servers = Get-Content "$env:userprofile\desktop\servers.txt"
Get-Job "Inv*" | Stop-Job  
Get-Job "Inv*" | Remove-Job  
$MAXJOB = "20"  
  
foreach ($Server in $Servers)  
{  
    $i++  
    Write-Progress -Activity "Creating job for Inventory Report.." -Status $Server -PercentComplete (100*$i/($Servers.count))  
    Invoke-command -Credential $Credential -AsJob -JobName "Inv.$Server" -ComputerName $Server -ScriptBlock {#SB-Start  
        #SB-Start  
        $GetInvs = gwmi win32_product 
  
        $LocalReport = @()  
        foreach ($GetInv in $GetInvs) {  
            $CName = $args[0] 
            $PName = $GetInv | % {$_.Name} 
            $Version = $GetInv | % {$_.Version}  
  
            $MyObject = New-Object PSObject -Property @{ 
            ServerName="$CName" 
            AppName="$PName" 
            Version="$Version"} 
            $LocalReport += $MyObject  
        }  
        return $LocalReport  
    #SB-END  
    } -ArgumentList $Server | Out-Null  
    $getRunningJobsCount = (Get-Job "Inv*" | ? {$_.State -eq "Running"}).count  
    while ($getRunningJobsCount -gt $MAXJOB)  
    {  
        Write-Progress -Activity "Reached maximum number of threads ($($MAXJOB))..." -Status "Wait till it gets reduced.." -PercentComplete (100*$i/($Servers.count))  
        Start-Sleep 10  
        $getRunningJobsCount = (Get-Job "Inv*" | ? {$_.State -eq "Running"}).count  
    }  
}  
  
$JobStatus = "Please wait"  
While (Get-Job "Inv*" | ? {$_.State -eq "Running"}) {  
    $CurrentRunningJobs = (Get-Job "Inv*" | ? {$_.State -eq "Running"}).count  
    Write-Progress -Activity "Jobs are running, please wait." -Status "$($CurrentRunningJobs) jobs running" -PercentComplete (100*($i-$CurrentRunningJobs)/$i)  
    #Get-Job | Get-Member  
    #(Get-Job).ChildJobs  
    Clear-Host  
    $c ="."  
    $JobStatus = "$JobStatus $c"  
    $JobStatus  
    Start-Sleep 1   
}  
  
$Result=@()  
foreach ($Job in (Get-Job | ? { $_.Name -like "Inv*"})) {  
    $JobResult = $null  
    $JobResult = Receive-Job $Job  
    $Result +=$JobResult  
    Remove-Job $Job  
}  
$Result = $Result | select ServerName, AppName, Version  
$Result | Export-Csv $ExportFileLocation -NoTypeInformation

Please do let me know in case of any query, happy scripting 🙂

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *