To explain it a little more, if you have executed Get-ADComputer
then you will get possibly an array of objects or a single object back.
I assume you are calling something like the following:
$serverList = Get-ADComputer -LDAPFilter '(cn=*DC*)';
This would get all the computers with DC
in their name.
Because you potentially have an array (more then one) or objects that you have process using the ForEach-Object
cmdlet (also aliased as %
or foreach
) is a good approach. Which is basically execute a script block for each record in the pipeline. However as you have experienced you are getting an object back from the query not a string. So you just have to choose a property to use.
For example if you use:
$serverList[0] | Get-Member
You will get all the properties of a computer object. gm
is also an alias for Get-Member
. E.g.
PS> $serverList[0] | gm
TypeName: Microsoft.ActiveDirectory.Management.ADComputer
Name MemberType Definition
---- ---------- ----------
Contains Method bool Contains(string propertyName)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEnumerator()
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Item ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPropertyValueCollection Item(string p...
DistinguishedName Property System.String DistinguishedName {get;set;}
DNSHostName Property System.String DNSHostName {get;set;}
Enabled Property System.Boolean Enabled {get;set;}
Name Property System.String Name {get;}
ObjectClass Property System.String ObjectClass {get;set;}
ObjectGUID Property System.Nullable`1[[System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, ...
SamAccountName Property System.String SamAccountName {get;set;}
SID Property System.Security.Principal.SecurityIdentifier SID {get;set;}
UserPrincipalName Property System.String UserPrincipalName {get;set;}
Quickly looking you can see that there is a DNSHostName property.
So to execute your command you could use something like:
$serverList = Get-ADComputer -LDAPFilter '(cn=*DC*)';
$serverList | ForEach-Object { New-PSSession -ComputerName $_.DNSHostName; }
However I will note that the New-PSSession
cmdlet doesn't do much except create a remoting session to a computer (PowerShell Remoting has to be enabled to support this). You would need to use the Invoke-Command
cmdlet to execute something from a script.
Example 1:
$serverList = Get-ADComputer -LDAPFilter '(cn=*DC*)';
$serverList | ForEach-Object { New-PSSession -ComputerName $_.DNSHostName; } | ForEach-Object { Invoke-Command -Session $_ -ScriptBlock { #Execute commands here }; };
Example 2:
Get-ADComputer -LDAPFilter '(cn=*DC*)' | % { Invoke-Command -ComputerName $_.DNSHostName -ScriptBlock { #Execute commands here }; };
The second example optimises out the New-PSSession
because it is not really needed if you are only going to call the Invoke-Command
without advanced options.
Also note there is no real need to store the result of Get-ADComputer
in a variable, you would only do that if Get-ADComputer
was took a long time to execute and you had to use it more then once.
The $_
is a pipeline variable that become whatever object in currently in the pipeline.
Updated
Specifically to use Invoke-Command
to execute an identical command against multiple computers you can use the -ComputerName
parameter to supply an array of strings. (This can be seen by looking at the help, i.e.-ComputerName <String[]>
. This would not be the case for all commands).
As mentioned the output from Get-ADComputer
is an object. So a string array compatible with the -ComputerName
parameter would be constructed by.
$serverList = @();
Get-ADComputer -LDAPFilter '(cn=*DC*)' | % { $serverList += $_.DNSHostName; }
Basically this creates a new array and adds each computers DNS host name to it, but you end up with string[]
. You would then be able to use:
Invoke-Command -ComputerName $serverList -ScriptBlock { #Execute commands here };
However also note that while is may appear you are only executing a single command under the hood it is almost always a number of PowerShell cmdlet. For example command pipeline have a silent | Out-Host
appended to them.
You could also wrap any of the commands in a function to execute a single command.
Hope that answers you question.