Reputation: 15
When i try to run invoke-command for every computer in Active-Directory , i will encounter the following error : "Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of strings. "
```
$Hosts_Array=Get-ADComputer -Properties CN -Filter * | Sort-Object | Select-Object CN
foreach ($i in $Hosts_Array) {
Invoke-Command -ComputerName $i -ScriptBlock { Get-Service -Name "sysmon64"}
}
```
I use the For loop to run the command for every computer that fetch from the AD.
Upvotes: 0
Views: 1759
Reputation: 61123
As commented, Select-Object
returns objects, in this case objects with just one property called 'CN'.
In fact, you don't need to ask for the CN at all, because Get-ADComputer
returns these properties by default:
DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName
You can simplify your code by doing:
$Hosts_Array = (Get-ADComputer -Filter *).Name | Sort-Object
foreach ($computer in $Hosts_Array) {
Invoke-Command -ComputerName $computer -ScriptBlock { Get-Service -Name "sysmon64" }
}
(Get-ADComputer -Filter *).Name
returns a string array of just the computer names, which can also be done using Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
P.S. I have changed the variable name to iterate with from $i
(usually used in numbered loops) into $computer
to make it clearer
Each object in AD has a Relative Distinguished Name
(RDN). This is the name of the object in it's parent OU/Container. For user, group, computer, and container objects, the RDN is the value of the cn
attribute (Common Name). For OU objects, the RDN is the value of the ou
attribute. For domain component objects, it's the dc
attribute.
The Name
property returns the RDN of any object.
Upvotes: 2
Reputation: 27481
This is probably the most common powershell question. Dereference the CN property into a string with foreach or select -expand or .CN and it will work. I would run the whole list at once so it runs in parallel.
$hosts_array = Get-ADComputer -Properties CN -Filter * | Sort-Object |
foreach-object CN
invoke-command $hosts_array { get-service sysmon64 }
Upvotes: 0
Reputation: 349
I would not use invoke-command
, as Get-Service
can be used to connect to computers remotely.
If you prefer to use get-service
, then you can try the following script:
$Hosts_Array = Get-ADComputer -Properties * -Filter *
$Obj = @()
$ServiceName = "sysmon64"
foreach ($Computer in $Hosts_Array)
{
$Hostname = $computer.name
# Check if computer is online
write-host "pinging $Hostname" -for Cyan
$ping = Test-Connection $Hostname -Count 1 -Quiet
if ($ping)
{
write-host "Computer found - $Hostname" -ForegroundColor Green
$Service = $null
$Service = Get-Service $ServiceName -ComputerName $Hostname -ErrorAction SilentlyContinue
if ($ServiceName)
{
write-host "Service $ServiceName found - $Hostname" -ForegroundColor Green
# create a hash table to store the date
$Hash = @{
Hostname = $Hostname
ServiceName = $Service.Name
Displayname = $Service.DisplayName
Status = $Service.Status
}
$Obj += New-Object psobject -Property $hash
}
else
{
write-host "Service NOT $ServiceName found - $Hostname" -ForegroundColor red
}
}
else
{
write-host "Computer found - $Hostname" -for Red
}
}
$Obj
Upvotes: 0
Reputation: 335
What happens if you place invoke-command into try/catch block?
$Hosts_Array=Get-ADComputer -Properties CN -Filter * | Sort-Object | Select-Object CN
foreach ($i in $Hosts_Array) {
try{
Invoke-Command -ComputerName $i -ScriptBlock { Get-Service -Name "sysmon64"}
}
catch{
write-output("Unable to resolve $i ")
}
}
Upvotes: 0