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 Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,463 questions
0 comments No comments
{count} votes

8 answers

Sort by: Most helpful
  1. Limitless Technology 39,516 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 45,906 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