param([Parameter(Mandatory=$true)][string] $ComputerFile) # This function strips stuff in parenthesis and trailing whitespace from the string passed, # which in my experience is usually what you want when looking at the BIOS model string. function massageModel { param([Parameter(Mandatory=$true)][string] $private:model) $private:model = $private:model -replace '\s*\([^)]+\)\s*', '' $private:model = $private:model -replace '\s+$', '' return $private:model } # Output files, didn't bother making them parameters... $modelsFile = 'computer-models-with-computername.txt' $modelsCountFile = 'computer-models-count.txt' # Prompt before overwriting files. if ((Test-Path $modelsFile) -or (Test-Path $modelsCountFile)) { "Output file(s) '$modelsFile' or '$modelsCountFile' exist." $private:answer = Read-Host 'Overwrite? (Y/n) [yes]' if ($private:answer -match '^n') { 'Aborting.'; exit 0 } } # Get the start time and display it before starting processing. $startTime = Get-Date "Start time: $startTime" if (!(Test-Path -PathType leaf $computerFile)) { "Error: $computerFile does not exist. Exiting..." exit 0 } # Get the computers. Skip lines with only whitespace (including blank lines). $computers = Get-Content $ComputerFile | Where-Object { $_ -match '\S+' } 'Found ' + $computers.Count + ' computers.' 'Processing computers with Get-WMIObject.' 'This might take a good long while depending on the amount of computers and their availability.' $models = @{} # Looks like it doesn't like, say, 1000 computers in the array passed to GWMI, # so I'm splitting it into chunks of 50 $computerCounter = 0 $tempComputers = @() foreach ($computer in $computers) { $computerCounter++ $tempComputers += $computer if ($computerCounter -eq 50) { Write-Host 'Processing a chunk of 50 computers (first:' $tempComputers[0] ', last:' $tempComputers[49] Get-WMIObject -computer $tempComputers -ErrorAction SilentlyContinue -Class Win32_ComputerSystem | Foreach { if ($_.Model) { $private:model = massageModel $_.Model $models.$(($_.Name).ToLower()) = $private:model } else { $models.$(($_.Name).ToLower()) = 'ERROR: No model' } } # Reset counter and empty temporary array $computerCounter = 0 $tempComputers = @() } # end of if $computerCounter -eq 50 } $models.GetEnumerator() | Sort-Object -property @{Expression='Name';Descending=$false},@{Expression='Value';Descending=$false} | Format-Table -AutoSize | Out-File $modelsFile $modelsCount = @{} $models.Keys | Foreach { $modelsCount.$($models.$_) += 1 } 'Found ' + $modelsCount.Count + ' unique models' $modelsCount.GetEnumerator() | Sort-Object -property @{Expression='Value';Descending=$true},@{Expression='Name';Descending=$false} | Format-Table -AutoSize | Out-File $modelsCountFile @" Start time: $startTime End time: $(Get-Date) Output files: $modelsFile, $modelsCountFile "@