I have written/nabbed code that is designed to iterate through a list of hostnames, grab the IP's, and then log users off if they are not 'Active' on the machine. Iterating through the hostnames and putting a list of IP's into an array list works perfectly:
$HostNames = "google.com","facebook.com","test.com" #Create an array with the hostnames.
$IPList = [System.Collections.ArrayList]@() #Create an empty array list so we can add/remove objects.
for ($i=0;$i -lt $HostNames.Length; $i++){ #Loop through the hostnames.
[System.Net.Dns]::GetHostAddresses($HostNames[$i]) | foreach {$IPList.Add($_.IPAddressToString) } #Get all the IPs for the host and add them to the array.
}
When I call:
echo $IPList
I get the expected result:
216.58.198.78
31.13.73.35
69.172.200.235
The piece of code I stole from https://stackoverflow.com/a/35848515/3718225 also works perfectly when including the hostname or IP directly, such as:
$sessions = qwinsta /server "localhost" | ?{ $_ -notmatch '^ SESSIONNAME' } | %{#Return information about the selected server | Using the previous command, do not return a row where anything matches SESSIONNAME in caps
$item = "" | Select "Active", "SessionName", "Username", "Id", "State", "Type", "Device" #Select what information to return
#All the items below this line trim up the session info.
$item.Active = $_.Substring(0,1) -match '>'
$item.SessionName = $_.Substring(1,18).Trim()
$item.Username = $_.Substring(19,20).Trim()
$item.Id = $_.Substring(39,9).Trim()
$item.State = $_.Substring(48,8).Trim()
$item.Type = $_.Substring(56,12).Trim()
$item.Device = $_.Substring(68).Trim()
$item
}
But when I do something like:
$HostNames = "google.com","facebook.com","test.com" #Create an array with the hostnames.
$IPList = [System.Collections.ArrayList]@() #Create an empty array list so we can add/remove objects.
for ($i=0;$i -lt $HostNames.Length; $i++){ #Loop through the hostnames.
[System.Net.Dns]::GetHostAddresses($HostNames[$i]) | foreach {$IPList.Add($_.IPAddressToString) } #Get all the IPs for the host and add them to the array.
}
for ($i=0;$i -lt $IPList.Length; $i++){ #For all of the IP's in the array.
$sessions = qwinsta /server $IPList[$i]| ?{ $_ -notmatch '^ SESSIONNAME' } | %{#Return information about the selected server | Using the previous command, do not return a row where anything matches SESSIONNAME in caps
$item = "" | Select "Active", "SessionName", "Username", "Id", "State", "Type", "Device" #Select what information to return
#All the items below this line trim up the session info.
$item.Active = $_.Substring(0,1) -match '>'
$item.SessionName = $_.Substring(1,18).Trim()
$item.Username = $_.Substring(19,20).Trim()
$item.Id = $_.Substring(39,9).Trim()
$item.State = $_.Substring(48,8).Trim()
$item.Type = $_.Substring(56,12).Trim()
$item.Device = $_.Substring(68).Trim()
$item
}
foreach ($session in $sessions){ #For all the sessions
if (($session.Username -ne "" -or $session.Username.Length -gt 1) -and ($session.State -eq 'Active')){ #So long as the session name is longer then 1 and not blank AND the session is not 'active'
#logoff /server $IPList $session.Id
Write-Host $IPList[$i] $session.Username $session.State #Disconnect the user.
}
}
}
I get an error:
Could not compare "0" to "13 11 14". Error: "Cannot convert the "System.Object[]" value of type "System.Object[]" to
type "System.Int32"."
At line:1 char:11
+ for ($i=0;$i -lt $IPList.Length; $i++){ #For all of the IP's in the a ...
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : ComparisonFailure
I have figured that I need to find a way to convert the ArrayList from a System.Object to a string. However, something like:
$IPList | out-string
Doesn't seem to work/be the solution. Why? What is the best way to convert this? I am not sure I understand why the $ArrayList stores strings as objects, and not strings.