gwmi Win32_UserAccount freezes PowerShell - powershell

So this is the core of my "Get Local Admin Account Info" script:
Get-WmiObject -Class Win32_UserAccount -ComputerName $server -Credential $Creds -Filter "Domain='$env:USERDOMAIN' AND SID LIKE '%500'"
Running this freezes both PS Console and the ISE, requiring Task Manager to kill them.
I understand based on other questions here on stackoverflow that querying Win32_UserAccount can result in a lot of data being pulled over the network. But I would think that specifying a single computer and a single SID would filter that volume of data down to a miniscule amount. I certainly don't have this problem querying other WMI Objects on remote servers.
Am I missing something?
EDIT: This freezes PS too:
gwmi win32_useraccount -computername $server "SID LIKE '%500'"

Need to specify the server name as the domain in the query. I.e "Domain='$server' AND SID LIKE '%500'"
This may still perform poorly though. See http://msdn.microsoft.com/en-us/library/aa394507(v=vs.85).aspx
Could also try filtering on LocalAccount property I.e "LocalAccount='$True'"

If you could do domain = and name =, it would be fast, because those are the indexes.
# fast
Get-WmiObject Win32_UserAccount -Filter "Domain='$env:USERDOMAIN' AND
name = 'js2010'"
Strangely, specifying localaccount by itself is fast, but not with a name or sid too.
# slow (AD joined)
Get-WmiObject Win32_UserAccount -Filter "localaccount = 'true' and
name = 'js2010'"
# fast
Get-WmiObject Win32_UserAccount -Filter "localaccount = 'true'" |
where name -eq js2010
# fast
get-wmiobject win32_useraccount -filter "localaccount = 'true'" |
where sid -like *500
# fast
get-wmiobject win32_useraccount -filter "domain = '$env:computername' and
sid like '%500'"
There's also a get-localuser:
# fast
Get-Localuser | where sid -like *500

Related

Powershell - Get a List of all Computers with their IP Address and Last Logged On User

i would like to get in Powershell a list of all computers (in my domain) with their IP Address and the last logged on user, the output should be something like this:
ComputerName | IpAddress | LastLoggedOnUser
ABC-123 1.2.3.4 Username
DEF-456 5.6.7.8 Username1
GHI-789 9.0.1.2 Username2
I have tried a lot of scripts but none of these worked so far :(
Thank you in advance!
Edit:
i tried this:
$computers = Get-ADComputer -Filter * | select Name
foreach($computer in $computers)
{
Get-WmiObject -ComputerName "$computer" -Class Win32_ComputerSystem | Select-Object UserName
}
but i get the error "The RPC Server is unavailable"
if i run the command
Get-WmiObject -ComputerName "[Computer Name]" -Class Win32_ComputerSystem | Select-Object UserName
it works, but shows me only one Computer.
You can append the scripts you have found to include the lastLoggedOnUser with the following command, but you would need acccess to the computer to retrieve this information.
Get-WinEvent -Computer (computer name) -FilterHashtable #{Logname='Security';ID=4672} -MaxEvents 1 | select #{N='User';E={$_.Properties[1].Value}}

Get-WmiObject from AD OU

I have a simple problem that I can't seem to work through. I need to know what servers are still running server 2008/R2.
I know that Win32_OperatingSystem's Name property contains the information that I'm looking for. I would like to be able to run Get-WmiObject against a collection of servers in an OU.
There are two problems that I'm having:
I can't figure out how to redirect the output of Get-ADComputer to something that Get-WmiObject -ComputerName can use. I think Get-ADComputer is outputting objects of type Microsoft.ActiveDirectory.Management.ADComputer, and Get-WmiObject is looking for type System.Management.ManagementObject. Here's what I came up with but it doesn't appear to work.
Get-WmiObject Win32_OperatingSystem -ComputerName (Get-ADComputer -filter * -SearchBase "OU=Member Servers,DC=Company,DC=Com" | select #{L="ComputerName";e={$_."name"}}) -Property name, csname | select csname, name | Format-Table -AutoSize
My temp workaround: I was able to create a CSV that contains the list of server names. I was able to use the CSV to run Get-WmiObject against. However, the OU contains "dead" servers. So when I try to run Get-WmiObject using the CSV-list of servers that came from AD there are connection timeouts and PowerShell waits a period of time to see if the dead server will respond. This really slows down the operation & we are working to clean this up. Until that happens, Is there a way to only pass the server names that pass a Test-Connection to Get-WmiObject?
Get-WmiObject win32_operatingsystem -ComputerName (Get-Content C:\Users\user1\Desktop\Servers.csv) -Property name, csname | select csname, name | Format-Table -AutoSize
Pick the name component first then it will pass it to the next pipeline object (select -object)
Get-WmiObject Win32_OperatingSystem -ComputerName ((Get-ADComputer -filter * -SearchBase "OU=Member Servers,DC=Company,DC=Com").Name)
Note: -ComputerName: accepts a string object so you cannot pass a base type object directly to that.

Powershell ForEach-Object {Start-Job -Scriptblock} not populating variables

Here is my code, it works and creates a job for each computer in the OU but does not populate the $Computer variable in my script block causing this to fail.
I am sure I am missing something small since I have never created jobs before in Powershell but after working on this for an hour or two I have been unable to figure out what I am missing.
#Gets all workstations that need to have software installed, if you don't want to uninstall all of the software from you will need to use a text document and Get-Content
$computers = Get-ADComputer -Filter * -SearchBase "OU=Workstation Test,OU=Workstations,OU=Workstations,DC=CONTOSO,DC=COM" | Select DNSHostName -ExpandProperty DNSHostname
$Computer
#Use Get-WMIObject to find the IdentifyingNumber
$Computers | ForEach-Object {Start-Job -Name "$Uninstall" -ScriptBlock {(Get-WmiObject -Class Win32_product -ComputerName $Computer -Filter {IdentifyingNumber LIKE '{CD95F661-A5C4-44F5-A6AA-ECDD91C2410B}'}).uninstall()}}
Instead of $computer you need to use $_.
$_ represents the current item in the pipeline.
Alternatively you could do:
ForEach ($Computer in $Computers) { Invoke-Command -ComputerName $Computer -ScriptBlock {(Get-WmiObject -Class Win32_product -Filter {IdentifyingNumber LIKE '{CD95F661-A5C4-44F5-A6AA-ECDD91C2410B}'}).uninstall()} }
Here you continue to use $Computer inside the foreach as it now gets populated with each item in the collection.
Also FYI your $computer line above the ForEach-Object is currently unnecessary (it's just outputting an empty variable, unless you've already populated it elsewhere).
Edit: per comments I also noticed that the start-job seemed redundant as -computername was being used on the wmi cmdlet. Invoke-command is preferred as it uses winrm, so I've modified it as such in my code above.

Any idea why I can't seem to execute two Get-WMIObject commands in the same Scriptblock?

I'm having a hell of a time with what seems like an utterly bizarre issue. I'm basically trying to inventory a bunch of workstations via WinRM and the Invoke-Command PowerShell cmdlet, but I'm running into grief when I try to execute more than one Get-WMIObject call at a time.
In this case, I'm specifically trying to get the model and serial number of the workstations and pipe them out to a CSV, making it important that the two commands are executed in the same Scriptblock, giving me something very similar to the below, basically.
Invoke-Command -ScriptBlock { Get-WmiObject Win32_ComputerSystem | Select Model ; Get-WmiObject win32_SystemEnclosure | Select serialnumber } -ComputerName (Get-ADComputer -Server [domain I care about] -filter 'name -Like "[types of computers I care about]"' | Select-Object -expand Name)
Even when run locally, Get-WmiObject Win32_ComputerSystem | Select Model ; Get-WmiObject win32_SystemEnclosure | Select serialnumber only returns the first command. I've tried swapping them around and the first command executes, while the second does not. Some of my colleagues report that it works just fine for them, others see the same result as me, and it doesn't seem to be a version issue, as one of the people for whom this works is running the same version of PowerShell as I am. (5.0.10240.16384)
Screenshot below of a few different command combinations. Anyone have any idea what's going on here?
If you change the list in the select-object cmdlets so both include the properties output by each, you will get the result you want (I think).
Invoke-Command -ScriptBlock { Get-WmiObject Win32_ComputerSystem | Select Model,SerialNumber ; Get-WmiObject win32_SystemEnclosure | Select model,serialnumber } -ComputerName localhost
That will get you output to the screen which should include all of the info. If you just want objects you can just capture the output and see that all of the properties are there.
$objects=Invoke-Command -ScriptBlock { Get-WmiObject Win32_ComputerSystem | Select Model ; Get-WmiObject win32_SystemEnclosure | Select serialnumber } -ComputerName (Get-ADComputer -Server [domain I care about] -filter 'name -Like "[types of computers I care about]"' | Select-Object -expand Name)
If you execute $objects | format-list * you will see that you have two objects, one with a Model and one with a SerialNumber.
Outputting different objects to a single CSV is another issue altogether. You get columns in the CSV based on the properties in the first object, so you will lose the SerialNumber property in the CSV.

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x80070 6BA

I have what should be a simple script that will connect to all the servers in a domain and build a table of all the services running on each server. However, when I try to automate the script to grab all the servers in a foreach loop I get an RPC error. If the $name variable is replaced with the server DNS name everything works as expected. I've checked the firewall and DCOM services on my system (win7) and the servers (2000 - 2008R2) and these are all enabled or disabled appropriately. So, I'm thinking something in the script is broke. I'm still learning powershell, so any tips are appreciated.
Here is the script so far.
$servernames = get-adobject -Filter 'ObjectClass -eq "Computer" ' -Searchbase "OU=Servers,DC=E,DC=BENEFIS,DC=ORG"
foreach ($name in $servernames) {
Get-WMIObject win32_service -computername $name -Property SystemName,Name,StartName,StartMode |
Format-table SystemName, Name, Startname >c:\serverservices.txt }
Each object you get back have a name property so you need to pass its value to the ComputerName parameter. In addition, to get computer object use the Get-ADComputer cmdlet, you also need to specify the Append switch when you export to the file otherwise content will be overwritten and what you'll see finally is the output of the last computer only.
$servernames = Get-ADComputer -SearchBase "OU=Servers,DC=E,DC=BENEFIS,DC=ORG" -Filter *
foreach ($name in $servernames)
{
Get-WMIObject win32_service -computername $name.Name -Property SystemName,Name,StartName,StartMode |
Format-table SystemName, Name, Startname | Out-File c:\serverservices.txt -Append
}