I have an ArrayList of computers where I want to test against each one, and remove failed ones from this list. The logic works up until removing the item from the ArrayList.
Failed computers are added to a second ArrayList, then iterated through to remove its computers from the first ArrayList; otherwise I get the error about iterating through an ArrayList and invoking Remove() on it at the same time. I’ve scoured many online resources and PS books for ideas, and it appears my code should work. Scope issue?
Thanks, Olaf. Like you, I did not get any errors. The problem is that the specified $Computer is not removed from the ArrayList when invoking Remove($Computer).
In the meantime, I did a workaround. I use [string]$ComputerName as the cmdlet parameter for getting the computer names, then 2 ArrayLists; one for accessible computers, and one for failed, then pass them to a custom object.
The problem is that the specified $Computer is not removed from the ArrayList when invoking Remove($Computer).
But that was it what I wanted to say. Besides I didn't get any errors it was working just as expected.
Probably you have a good reason for using arraylists instead of arrays. But another proper way to deal with such a challenge is to recreate the array without the elements you want to remove.
Personally, I think your function is returning way to generic information. You get a list of computers that failed. Why did they fail? Next, you are going to loop through those computers to investigate what happened. Returning a list of computers doesn’t get you much in either instance, it’s not “Powershell-y”.
Take a look at this:
function Get-WsManStatus {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true,
Position = 1)]
[ValidateCount(1,32)]
[string[]]$ComputerName
)
begin{}
process {
$results = foreach ($Computer in $ComputerName) {
$Computer = $Computer.ToUpper()
try {
Write-Verbose ("Validating WsMan functionality enabled on {0}" -f $Computer)
$test = Test-WSMan -ComputerName $Computer -ErrorAction Stop
Write-Verbose ("WSMan working on {0}" -f $Computer)
$props = @{
ComputerName = $Computer
Status = "SUCCESS"
Message = $test
}
} catch {
Write-Verbose ("WSMan test failed on {0}" -f $Computer)
$props = @{
ComputerName = $Computer
Status = "FAILED"
Message = $_
}
} #try wsman
New-Object -TypeName PSObject -Property $props
} #foreach computer
}#process
end {
$results
}
} #function Get-WsManStatus
Get-WSManStatus -ComputerName "BadComputer", "GoodComputer", "AnotherGoodComputer"
Now you can use Group-Object, Where clauses, Sort and other analytics to tell you what failed and WHY it failed (e.g. not reacheable, WSMan failure specfics, etc.). Run the function against some computers and then do:
Thank you Olaf, Ron and Rob, for your excellent feedback.
While the same code I posted yesterday didn’t work, this morning it decided to work (no changes).
Rob - Appreciate the elaborate response; definitely a more effective approach. Being a new function, I was trying to get the core function working before tackling all the extras (why it failed, accept from pipeline, etc). Again, your example is much cleaner.