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
$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 🙂
Microsoft Teams’ Efficiency Mode Arrives for Low‑End Devices
Microsoft is rolling out an Efficiency Mode for Microsoft Teams designed to…
How Attackers Abuse Microsoft Teams and Quick Assist: Inside the Helpdesk Impersonation Playbook
A new wave of attacks is quietly abusing everyday collaboration tools to…
New RDP Alert After April 2026 Security Update Warns of Unknown Connections
Microsoft’s April 2026 Patch Tuesday introduced a small-looking but important change to…
RedSun: New Microsoft Defender Zero-Day Lets Unprivileged Users Gain SYSTEM Access
A freshly disclosed zero-day vulnerability in Microsoft Defender, dubbed "RedSun," has raised…
Thanks for the blog. It was very helpful.