Write-progress trouble with foreach loop

21,841

In the final loop, you need to increment your counter after every WMI query, then call Write-Progress using the updated value.

Cleaned up and nicely formatted:

$i = 0    

foreach($livePC in $livePCs)
{
   $entry = Get-WmiObject win32_product -computername $livePC -Filter "Name LIKE '%db2%'"

   # do the work
   if ($entry -ne $null)
   {
     $livePc,$entry | out-file c:\script\db2pcs.txt -Encoding ASCII -Width 50 -Append
     Write-Host "$livePC has DB2 installed"
   } 
   else
   {
     write-host "$livePC does not have DB2 installed"
   }

   # update counter and write progress
   $i++
   Write-Progress -activity "Scanning WMI . . ." -status "Scanned: $i of $($livePCs.Count)" -percentComplete (($i / $livePCs.Count)  * 100)
}
Share:
21,841
John
Author by

John

Updated on August 30, 2020

Comments

  • John
    John over 3 years

    Probably a really simple answer to this one. I am having trouble getting write-progress to work. I'm fairly sure the issue is with my variables, but I can't seem to figure out exactly what.

    What it does now is bombs on the first run when none of the output files exist. It will tell me:

    Write-Progress : Cannot validate argument on parameter 'PercentComplete'. The 300 ar gument is greater than the maximum allowed range of 100. Supply an argument that is less than 100 and then try the command again.

    The "300 argument" it mentions is a different, random number each time.

    Now if I run the script again with the livepcs.txt now existing, it may work and it may not work. Even if it does, the progress bar starts half way across.

    This is my first time trying to get write-progress working, so it's probably something very simple, but I'm not too sure what to look for as of yet. Any advice you could offer would be greatly appreciated.

    Final code:

        #Import active directory module
    Import-Module active*
    
    #Query AD for all computers by name filter, AND that have an IP listed in AD, store in variable (use line 10)
    
    $PCs = Get-ADComputer -Properties * -Filter {name -like "PCNameDomainPrefix*"} | Where-Object {$_.Ipv4Address -ne $null} | select name,ipv4address
    
    #Dump list of PCs into CSV
    $PCs | Export-Csv c:\script\pcs.csv
    
    #Begin foreach loop to see which servers are alive
    
    $i = 0
    
    $livePCs = ForEach($name.name in $PCs) #specify the name string using .name after the variable
        {
        $entry = Test-Connection $name.name -count 1 -quiet #Test-connection pings. The -quiet parameter forces a boolean result (True/False).
        if ($entry -eq "True") {out-file -InputObject $name.name -Encoding ASCII -Width 50 -Append c:\script\livepcs.txt ; Write-Host "$name.name pings"} 
        else { write-host "server $name could not be contacted"}
        $i++
        Write-Progress -activity "Pinging servers . . ." -status "Pinged: $i of $($PCs.Count)" -percentComplete (($i / $PCs.Count)  * 100)
        }
    
    
    #Announce WMI portion of script, clear host to get rid of status bar    
    Clear-Host
    Write-Host
    Write-Host
    Write-Host
    Write-Host "Beginning WMI scans. Please wait..."
    Write-Host
    Write-Host
    Write-Host
    
    
    $livePCs = Get-Content C:\script\livepcs.txt
    
    #Begin foreach loop to query each live machine using WMI. 
    
    $i = 0    
    
    foreach($livePC in $livePCs)
    {
       $entry = Get-WmiObject win32_product -computername $livePC -Filter "Name LIKE '%db2%'"
    
       # do the work
       if ($entry -ne $null)
       {
         $livePc,$entry | out-file c:\script\db2pcs.txt -Encoding ASCII -Width 50 -Append
         Write-Host "$livePC has DB2 installed"
       } 
       else
       {
         write-host "$livePC does not have DB2 installed"
       }
    
       # update counter and write progress
       $i++
       Write-Progress -activity "Scanning WMI . . ." -status "Scanned: $i of $($livePCs.Count)" -percentComplete (($i / $livePCs.Count)  * 100)
    }
    
  • John
    John over 11 years
    I posted my final code for anyone who's curious (and for the good of mankind). I went ahead and added another write-progress routine for the test-connection portion of my script because I will eventually need to query several hundred PCs. Anyway, thanks again for the help!