Powershell script with foreach loop that exports to csv randomly hangs

Chopad 1 Reputation point
2022-07-18T18:25:40.52+00:00

I have a PowerShell script that reads a list of computers, gets BIOS info via WMI and exports that info to a CSV. It will stop working after a random number of iterations, no errors, the script just hangs until I kill it. Am I running into some type of limitation exporting the data to a CSV? This seems like it should work.

Thanks

Function Write-Log {  
  
    [CmdletBinding()]  
    Param(  
    [Parameter(Mandatory=$False)]  
    [ValidateSet("INFO","WARN","ERROR","FATAL","DEBUG")]  
    [String]  
    $Level = "INFO",  
    [Parameter(Mandatory=$True)]  
    [string]  
    $Message,  
    [Parameter(Mandatory=$False)]  
    [string]  
    $logfile = "C:\Temp\GetBiosinfo\BIOSLog.log"  
    )  
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")  
    $Line = "$Stamp $Level $Message"  
    If($logfile) {  
        Add-Content $logfile -Value $Line  
    }  
    Else {  
        Write-Output $Line  
    }  
}  
  
$ComputerList = Get-Content -Path "C:\Temp\GetBiosInfo\computerlist.txt"  
foreach ($computerfromlist in $ComputerList)  
    {  
        $computerinfo = "" | Select "Hostname", "Manufacturer", "Model", "BIOSVersion"  
        $computername = $computerfromlist  
        If(Test-Connection $computername -Count 1 -Quiet)  
            {  
                Start-Sleep -Seconds 5  
                Write-Log -Message "$computername is online"  
                $Model = (Get-WMIObject  Win32_ComputerSystemProduct -ComputerName $computername).Name  
                $BIOSManuf = (Get-WmiObject -Class Win32_BIOS -ComputerName $computername).Manufacturer  
                $BIOSVersion = (Get-WmiObject -Class Win32_BIOS -ComputerName $computername).SMBIOSBIOSVersion  
                Start-Sleep -Seconds 5  
                Write-Log -Message "$computername WMI Info Gathered"  
  
                If(($BIOSManuf -ne $null) -or ($BIOSVersion -ne $null) -or ($Model -ne $null))  
                    {  
                        $computerinfo.Hostname = $computername  
                        $computerinfo.Manufacturer = $BIOSManuf  
                        $computerinfo.Model = $Model  
                        $computerinfo.BIOSVersion = $BIOSVersion  
                        $computerinfo | Export-csv -Path "C:\Temp\GetBIOSInfo\BIOSInfo.csv" -Append -NoTypeInformation  
                        Start-Sleep -Seconds 5  
                        Write-Log -Message "$computername online info updated in CSV"  
                    }  
                Else  
                    {  
                        $computerinfo.Hostname = $computername  
                        $computerinfo.Manufacturer = "Connected but no response"  
                        $computerinfo.Model = ""  
                        $computerinfo.BIOSVersion = ""  
                        $computerinfo | Export-csv -Path "C:\Temp\GetBIOSInfo\BIOSInfo.csv" -Append -NoTypeInformatio  
                        Start-Sleep -Seconds 5  
                        Write-Log -Level WARN -Message "$computername online but no response info updated in CSV"  
                    }  
            }  
  
         Else  
                {  
                    Start-Sleep -Seconds 5  
                    Write-Log -Level WARN -Message "$computername is NOT online"  
                    $computerinfo.Hostname = $computername  
                    $computerinfo.Manufacturer = "Can't Connect"  
                    $computerinfo.Model = ''  
                    $computerinfo.BIOSVersion = ''  
                    $computerinfo | Export-csv -Path "C:\Temp\GetBIOSInfo\BIOSInfo.csv" -Append -NoTypeInformation  
                    Start-Sleep -Seconds 5  
                    Write-Log -Message "$computername not online info updated in CSV"  
                }  
     }  
Windows for business Windows Server User experience PowerShell
0 comments No comments
{count} votes

8 answers

Sort by: Most helpful
  1. Limitless Technology 39,916 Reputation points
    2022-07-19T15:31:14.44+00:00

    Hello Chopad,

    You can set Verbose modes in Powershell to get more information about the processes and where it may fail during its run. This may help you to understand better the issue and troubleshoot it more efficiently.

    Add the next at the beginning of your script:

    Set-PSDebug -Trace 2
    $VerbosePreference="Continue"

    Reference and more advanced details are available in the next official article: https://devblogs.microsoft.com/scripting/use-powershell-to-write-verbose-output/

    ----------------------------------------------------------------------------------------------------------

    --If the reply is helpful, please Upvote and Accept as answer--

    0 comments No comments

  2. Rich Matheisen 47,901 Reputation points
    2022-07-19T15:34:21.483+00:00

    Give this a try. It reduces the size of the WMI data returned by the Get-WMIObject (and the time it takes for WMI to complete on the remote machine -- the difference can be substantial).

    I removed the "Start-Sleep" stuff and added additional logging (at least for the Get-WMIObject parts):

    Function Write-Log {  
              
        [CmdletBinding()]  
        Param(  
            [Parameter(Mandatory = $False)]  
            [ValidateSet("INFO", "WARN", "ERROR", "FATAL", "DEBUG")]  
            [String]  
            $Level = "INFO",  
            [Parameter(Mandatory = $True)]  
            [string]  
            $Message,  
            [Parameter(Mandatory = $False)]  
            [string]  
            $logfile = "C:\Temp\GetBiosinfo\BIOSLog.log"  
        )  
        $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")  
        $Line = "$Stamp $Level $Message"  
        If ($logfile) {  
            Add-Content $logfile -Value $Line  
        }  
        Else {  
            Write-Output $Line  
        }  
    }  
         
    $computerinfo = [ordered]@{  
        Hostname     = ""  
        Model        = ""  
        Manufacturer = ""  
        BIOSVersion  = ""  
    }  
         
    Get-Content -Path "C:\Temp\GetBiosInfo\computerlist.txt" |  
        ForEach-Object {  
            $computerinfo.Hostname = $_  
            If (Test-Connection $_ -Count 1 -Quiet) {  
                Write-Log -Message "$_ is online"  
                Write-Log -Message "Getting Name"  
                $Model          = (Get-WmiObject  Win32_ComputerSystemProduct -ComputerName $_ -Property Name).Name  
                Write-Log -Message "Name finished"  
                Write-Log -Message "Getting Manufacturer and SMBIOSBIOSBVersion"  
                $BIOSStuff      = Get-WmiObject -Class Win32_BIOS -ComputerName $_ -Property Manufacturer,SMBIOSBIOSVersion  
                Write-Log -Message "Manufacturer and SMBIOSBIOSBVersion finished"  
                $BIOSManuf      = $BIOSStuff.Manufacturer  
                $BIOSVersion    = $BIOSStuff.SMBIOSBIOSVersion  
                Write-Log -Message "$_ WMI Info Gathered"  
                         
                If ( $BIOSManuf -or $BIOSVersion -or $Model ) {  
                    $computerinfo.Manufacturer = $BIOSManuf  
                    $computerinfo.Model = $Model  
                    $computerinfo.BIOSVersion = $BIOSVersion  
                    Write-Log -Message "$_ online info updated in CSV"  
                }  
                Else {  
                    $computerinfo.Manufacturer = "Connected but no response"  
                    $computerinfo.Model = ""  
                    $computerinfo.BIOSVersion = ""  
                    Write-Log -Level WARN -Message "$_ online but no response info updated in CSV"  
                }  
            }  
            Else {  
                Write-Log -Level WARN -Message "$_ is NOT online"  
                $computerinfo.Manufacturer = "Can't Connect"  
                $computerinfo.Model = ''  
                $computerinfo.BIOSVersion = ''  
                Write-Log -Message "$_ not online info updated in CSV"  
            }  
            [PSCustomObject]$computerinfo  
        } | Export-Csv -Path "C:\Temp\GetBIOSInfo\BIOSInfo.csv" -NoTypeInformation  
    
    0 comments No comments

  3. Chopad 1 Reputation point
    2022-07-19T15:47:35.737+00:00

    Thanks, trying it right now.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.