Running a powershell script against all the computers in Active Directory - powershell

I have written a script that generates some information but I need to run it on over 160 computers in an active directory. I don't want to run this script on each machine individually, is there any way of executing this script all all the machines from one centralized location?
invoke-command -ComputerName test-pc -ScriptBlock {gwmi win32_service | Select-object Name, PathName | where-object {$_.PathName -notlike '"*' -and $_.PathName -like "*\* *\*"}}
I don't want to be logging on to each machine individually. Is there quicker way? There must be.
Any help will be much appreciated.
Sohail.
Updated version:
invoke-command -ComputerName #(Get-ADComputer -Filter {Name -like "GBST*"} | Select-Object Name) -ScriptBlock {gwmi win32_service | Select-object Name, PathName | where-object {$_.PathName -notlike '"*' -and $_.PathName -like "*\* *\*"}}
Error message:
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.
At line:1 char:2
+ invoke-command -ComputerName #(Get-ADComputer -filter {Name -like "GBSU1*"} | S ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.String[]:String[]) [Invoke-Command], ArgumentException
+ FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

Just to make it shorter :
(Get-ADComputer -Filter 'Name -like "GBSU*"').Name | % {
Get-WMIObject Win32_Service |
Select-Object Name, PathName |
Where-Object { $_.PathName -notlike '"*' -and $_.PathName -like "** **" }
}
As pointed out by #bluuf :
This is actually not a 'good' solution since Get-WmiObject supports
the ComputerName parameter : Invoke-Command shouldn't be used at all
in this case.

There is a syntax error in your revised example where you kept the "*" in the Filter. You can't filter for all then narrow your results. Asterisk is implied when filtering based on properties.
I also added the ".Name" property to the computer search to only pass that to the invoke-command section. I tried the following code and it seemed to work.
invoke-command -ComputerName #((Get-ADComputer -Filter 'Name -like "GBST*"').Name) -ScriptBlock {gwmi win32_service | Select-object Name, PathName | where-object {$_.PathName -notlike 'C:\Windows\system32\*' -and $_.PathName -like 'C:\Program Files\*'}}

Related

PowerShell Script to pull servers in AD and then search SERVICES running under the Local Administrator account

New to PowerShell, attempting to cobble scripts together to:
Pull a list of Servers in Active Directory (done).
Query each server for a list of SERVICE accounts running under ADMINISTATOR credentials.
Can anyone guide me...prefer to export out to a CSV file, etc.
THANK YOU!
THIS IS WHAT I HAVE:
Import-Module ActiveDirectory
$Serverlist = Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true"' `
-Properties Name
Sort-Object -Property Name |
foreach ($Server in $Serverlist) {
$Server
Get-WmiObject Win32-Service | Select DisplayName, StartName | Where-Object {$_.StartName -eq "administrator"}
GETTING THESE ERRORS:
At line:5 char:18
+ foreach ($Server in $Serverlist) {
+ ~~
Unexpected token 'in' in expression or statement.
At line:5 char:17
+ foreach ($Server in $Serverlist) {
+ ~
Missing closing ')' in expression.
At line:5 char:32
+ foreach ($Server in $Serverlist) {
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
Assuming you have permissions to remotely query those hosts you can try the following:
$computers = (Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true"').DNSHostName
Get-CimInstance Win32_Service -Filter "StartName LIKE '%Administrator%'" -ComputerName $computers
| Select-Object DisplayName, StartName, PSComputerName
Notes
Get-CimInstance and Get-WmiObject (replaced in this example, since its no longer maintained in new PowerShell versions) can invoke queries in parallel, hence no loop is required.
Both cmdlets allow queries with WQL. Faster filtering this way than with powershell.
Only real reason to use Get-WmiObject instead of Get-CimInstance could be if using DCOM as your remoting protocol. At which point you could use New-CimSessionOption -Protocol DCOM and connect using a CimSession. Functionality for both cmdlets is mostly the same.
You should include PSComputerName in your Select-Object statement to understand from which computer the object is coming from.

get deactivated computers in ad from csv list

i'm tryin to figure out which computers are deactivated. for that i provide the computer names in a csv list. i just want to output the computers which are deactivated. this is what i have. unfortunately i get all deactivated computers. but i only want that names provided in the csv
Import-CSV -Path "C:\pc_names" | Select -expand Name | Get-ADComputer -searchbase 'XXX' -Filter {(Enabled -eq $False)} -Properties Name, OperatingSystem | Export-CSV “C:\Temp\DisabledComps.CSV” -NoTypeInformation
The problem is likely in the Get-ADComputer command, you specify a SearchBase (assumedly an OU), and a filter for all disabled computers - but never actually include the name of the PC that you piped in from the CSV, so it just returns every disabled PC under that search base.
Try something like this instead;
Import-CSV -Path "C:\pc_names" | Select -Expand Name | Get-ADComputer -SearchBase 'XXX' -Filter {(Enabled -eq $False) -and ($_.Name)} -Properties Name, OperatingSystem | Export-CSV "C:\Temp\DisabledComps.CSV" -NoTypeInformation
Note the $_.Name in the filter.
I've probably got that filter syntax wrong - but that should be the cause.
There is no way you can test if the computername is to be found in an array of names using the -Filter parameter..
You need to first collect computer objects within your SearchBase OU and filter the disabled ones only.
Following that, you filter out the ones that can be found in the $pcNames array using a Where-Object clause:
$pcNames = (Import-Csv -Path "C:\pc_names.csv").Name
Get-ADComputer -SearchBase 'XXX' -Filter "Enabled -eq 'False'" -Properties OperatingSystem |
Where-Object { $pcNames -contains $_.Name } | # or: Where-Object { $_.Name -in $pcNames }
Export-Csv -Path "C:\Temp\DisabledComps.csv" -NoTypeInformation
Note: Get-ADComputer by default already returns these properties: DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName. That means you only have to ask for the extra property OperatingSystem in this case
It's pretty obvious that something like this ignores what's piped in and returns many computers.
'comp001' | get-adcomputer -filter 'Enabled -eq $False'
If you wait until the end, there is an error message:
get-adcomputer : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.
At line:1 char:13
+ 'comp001' | get-adcomputer -filter 'Enabled -eq $false'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (comp001:String) [Get-ADComputer], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
You can do get-adcomputer inside a foreach loop and test Name as well:
$list = echo comp001 comp002 comp003
$list | % { get-adcomputer -filter 'Enabled -eq $False -and Name -eq $_' }

Fixing simple Get-ADComputer : The server has returned the following error: invalid enumeration context

Why did the below simple AD cmdlets fail? I'm trying to get all Windows Server OS that is online in my AD domain, into variable.
$Servers = Get-ADComputer -Filter { Enabled -eq $True -and OperatingSystem -like "*Server*" } -Properties OperatingSystem -SearchBase "DC=DOMAIN,DC=com" |
Where-Object { Test-Connection $_.Name -Count 1 -Quiet } |
Select-Object -ExpandProperty Name
However, it is error:
Get-ADComputer : The server has returned the following error: invalid enumeration context.
+ $Servers = Get-ADComputer -Filter { Enabled -eq $True -and OperatingS ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ADComputer], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
How to make it works?
Get-ADComputer makes a paged query to Active Directory, and then starts outputting the results one-by-one.
If PowerShell takes too long between initially sending the query and then subsequently asking for the next page of the result set, the page cursor on the DC basically times out to free up resources and you get invalid enumeration context.
Instead of piping the output directly to Where-Object { Test-Connection ... }, which in turn "backs up" the pipeline every time we're waiting for a ping to timeout, make the Get-ADComputer call in a nested pipeline (enclose it it ()):
$Servers = (Get-ADComputer -Filter { Enabled -eq $True -and OperatingSystem -like "*Server*" } -Properties OperatingSystem -SearchBase "DC=DOMAIN,DC=com") |
Where-Object { Test-Connection $_.Name -Count 1 -Quiet } |
Select-Object -ExpandProperty Name

Command Get-ADUser -Filter doesn't work in PSSession

I'm doing a script for changing user account AD with a GUI.
When selecting a user in a list, I want to show all the groups of which he is a member.
For the order it is OK but in a PSSession the command does not work, the -Filter parameter does not recognize the variable
$SessionAD = New-PSSession -ComputerName $AD
Invoke-Command $SessionAD -Command {Import-Module ActiveDirectory}
Import-PSSession $SessionAD -Module ActiveDirectory
...
$var = $ListeUsers.SelectedItem
$GroupsMember = Get-ADUser -Filter {Name -like $var} -Property MemberOf |
Select -ExpandProperty MemberOf |
Get-ADGroup -Property MemberOf |
Select Name
Error : La variable : « var » trouvée dans l’expression : $var n’est pas définie.
+ CategoryInfo : InvalidArgument : (:) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : La variable : « var » trouvée dans l’expression : $var n’est pas définie.,Microsoft.ActiveDirectory.Management.Commands.GetADUser
+ PSComputerName : AD-01
With the code below the command runs fine, but I can not retrieve the values of the variable $GroupsMember:
Invoke-Command -Session $SessionAD -ArgumentList $var,$GroupsMember -ScriptBlock {
Param($var, $GroupsMember)
$GroupsMember = Get-ADUser -Filter {Name -like $var} -Property MemberOf |
Select -ExpandProperty MemberOf |
Get-ADGroup -Property MemberOf |
Select Name
}
Finally found a solution to your problem.
In your code the braces in Get-ADuser -Filter{...} are the problem.
you can update your code like that :
$SessionAD = New-PSSession -ComputerName "SVADDS01.Mylab.local"
Invoke-Command $SessionAD -Command {Import-Module ActiveDirectory}
Import-PSSession $SessionAD -Module ActiveDirectory | Out-Null
$ADUSers = Get-ADuser -Filter *
$var = $ADUSers | Select-Object -Property Name, SamaccountName | Out-GridView -OutputMode Single
$GroupsMember = Get-ADUser -Filter ('Name -eq "' + $var.Name + '"') -Property MemberOf |
Select -ExpandProperty MemberOf |
Get-ADGroup -Property MemberOf |
Select Name
$GroupsMember
Get-PSSession | Remove-PSSession
Note that in the current solution :
My $var object contains an instance of a Get-ADUser object. this is the reason why I'm using $var.Name in the search
the Get-ADUser use, like you, a Filter but this one is a String built from the previous selection

How To Ignore Error In Powershell Script (ErrorAction: SilentlyContinue not suppressing error)

I have a Powershell script that lists all the users/groups in the local administrators group for all computers in a designated OU in Active Directory.
The script works perfectly locally (if I run it against the local machine only) but when I run it against remote machines, it technically works but it throws a consistent error that I don't know how to filter out.
Here is the script (NOTE: must be running from ActiveDirectory PS console to use Get-ADComputer):
Get-ADComputer -SearchBase 'OU=ou01,dc=domain,dc=local' -Filter 'ObjectClass -eq "Computer"' `
| ForEach-Object {
Get-WmiObject win32_groupuser -cn $_.name -ErrorAction SilentlyContinue `
| Where-Object { $_.groupcomponent -match 'administrators' } `
| ForEach-Object -ErrorAction SilentlyContinue {[wmi]$_.partcomponent } `
| Select-Object __SERVER,Caption
} | Format-Table -Property * -AutoSize
Here are the results (correct result is in first line, error below that):
__SERVER Caption
-------- -------
workstation_name workstation_name\Administrator
Cannot convert value "\\workstation_name\root\cimv2:Win32_Group.Domain="DOMAIN",Name="Domain Admins"" to type "System.Management.ManagementObject". Error: "Not found "
At line:1 char:306
+ Get-ADComputer -SearchBase 'OU=ou01,dc=domain,dc=local' -Filter 'ObjectClass -eq "Computer"' | ForEach-Object { Get-WmiObject win32_groupuser -cn $_.name -ErrorAction SilentlyContinue | Where-Object { $_.groupcomponent -match 'administrators' } | ForEach-Object -ErrorAction SilentlyContinue {[wmi]$_. <<<< partcomponent } | Select-Object __SERVER,Caption } | Format-Table -Property * -AutoSize
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
I have unsuccessfully tried to use -ErrorAction SilentlyContinue, is there another way to suppress this message? Not sure what I am missing.