I am working on a script that will be running remote PowerShell on a large list of servers, these servers may randomly change domains. So, for instance, a list might have 50 servers on domain A and 150 servers on domain B.
I have been successful in executing this script via using wildcards/regex to determine which domain the server is joined to.
That being said, using names is an awful solution, and I would like to find a better way to determine the correct credentials to use. I would like to avoid using Invoke-Command
just to test the connection. The best solution I have found is to use something akin to the following:
try {
$session = New-PSSession -Credential $a -ComputerName $_ -ErrorAction Stop
} catch {
$session = New-PSSession -Credential $b -ComputerName $_
}
In this case, $_
is simply a string, a computer name. The credential objects are defined via Get-Credential
.
I feel like this could be much more efficient, in theory. Additionally, it simply does not work. While me using if/else with the exact same contents functions perfectly, the code in catch
always fails with:
New-PSSession : One or more computer names are not valid.
This does not make much sense to me, since the syntax I use functions perfectly everywhere outside catch
. For instance, in the above example, the code in try
works. Swapping the contents of each block still results in failure of catch
. I have also tried using Remove-PSSession $session
, however that did not seem to help.
So my question is:
You could use a DNS lookup to get the FQDN from the hostname, remove the hostname from the FQDN to get the domain name, then lookup the credentials by the domain name in a hashtable.
$credentials = @{
'example.com' = $a
'example.com' = $b
...
}
...
$serverList | ForEach-Object {
$fqdn = [Net.Dns]::GetHostByName($_) | Select-Object -Expand HostName
$null, $domain = $fqdn -split '\.', 2
$cred = $credentials[$domain]
$session = New-PSSession -Credential $cred -ComputerName $fqdn
...
}