Tuesday, January 13, 2015

(PowerShell) Enumerating Local User Accounts

This was mildly annoying so I thought I would put it here so next time I run into this I know how to do it. I wanted to simply enumerate all of the standard user accounts on the LocalMachine using a one liner PowerShell cmdlet. Most of methods I found online with a google search said to use [ASDI]. This was more convoluted than I wanted to get to do this seemingly simple thing.

After stewing for a bit I started digging through the Get-WmiObject cmdlet and there it was!!!

-Class Win32_UserAccount


So I took a look at the available properties and output the usernames only.

Get-WmiObject -Class Win32_UserAccount | Get-Member













So I just formatted the output to include just the Name property and there it is.

Get-WmiObject -Class Win32_UserAccount | Format-List -Property Name









But we are not going to stop there :)
I went ahead and pulled just the admin account.

Get-WmiObject -Class Win32_UserAccount | Where-Object{$_.Name -eq "Administrator"}









That was only a subset of the properties so I used Format-List -Property * to pull up the rest of them

Get-WmiObject -Class Win32_UserAccount | Where-Object{$_.Name -eq "Administrator"} | Format-List -Property *


















Now that I can see all of the properties I can check for certain properties across all of the accounts. For example I can list all of the accounts that are currently disabled.

Get-WmiObject -Class Win32_UserAccount | Where-Object{$_.Disabled -eq $true}












If I break my one line rule I can even modify properties of the user object, for example lets say that I wanted to enable the Administrator account for some reason (Don't do this, I am just figuring out how this works and enabling the Administrator account is a bad idea).

[Note: The .Put() thing, this threw me for a few minutes. Remember when you use any of the Get- commands what you are actually doing is grabbing templates of the objects and then filling them with data PowerShell grabs from the OS. What I changed when I set Disabled = $false is the value in the new object I created. The .Put() command takes my object and saves it back to OS so that the changes take effect. Without the .Put() nothing changes on the OS]

$tempuser = Get-WmiObject -Class Win32_UserAccount | Where-Object{$_.Name -eq "Administrator"}

$tempuser.Disabled = $false

$tempuser.Put()



Now if I run my account disabled test from above I get this.

Get-WmiObject -Class Win32_UserAccount | Where-Object{$_.Disabled -eq $true}




Friday, January 9, 2015

(PowerShell) Filtering netstat output

Update:
This works great :)

netstat -bno


Since standard Windows command line tools can easily interact with PowerShell cmdlets I thought I would try some grep style string filtering.

Lets find all of the ports that are listening on our system:

netstat -nao | Select-String LISTENING

Output:



Or search for a specific port:

netstat -nao | Select-String :139

Output:




Search for all of the UDP ports:

netstat -nao | Select-String UDP

Output:














Now look for all ports that are UDP and on port 1900:

netstat -nao | Select-String UDP | Select-String :1900








:)

Thursday, January 8, 2015

(PowerShell) Clock App Runtime

I wanted to figure out if there was a way in PowerShell to do something like the time command does in Linux (Calculates the amount of time in ms that an application takes to execute. It turns out that that it is built right in to PowerShell in the form of a cmdlet (Measure-Command).

I decided to start with something simple that would take a little time to complete.

Note: The {braces} define a statement block and in this case is used to combine the actions that you want to time. 

Measure-Command {Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue}

Output:












So that worked pretty much how I wanted. So I next I wanted to see if it would time something other than PowerShell cmdlets (like a regular Windows App). I wanted to do something that would take a bit of time so I copied a large file. I checked the PowerShell alias table to make sure robocopy was not an alias for a cmdlet  and gave this a try.

First I found a big file (did not care what it was, just that it was between 100-200MB)

Get-ChildItem -Path $PWD | Where-Object {$_.Length -gt 100MB -and $_.Length -lt 200MB}

Output:





Then ran the speed test on robocopy

Measure-Command {robocopy.exe $PWD $HOME MRT.exe}

Output:











So an executable without a GUI can be timed with no problem. What about a .exe that a user interacts with? It seemed to make sense that something like this would work.

Measure-Command {calc.exe}

Output:











Bad luck, it does not work, it only timed the launching of the app and then returned as soon as the window appeared. I need to do more research but I think that GUI apps disconnect themselves from the shell once they are launched and can not be measured this way :(.

Wednesday, January 7, 2015

(PowerShell) WindowsOS Version (Linux Style)

I decided to do this blog to prove that I can learn something that is worth writing down (and using again at a later time) everyday. It might boring on some days but hopefully I will have some useful info here. So off we go...

==================================================

I wanted a way to to list the Windows OS Version similar to how I can
in Ubuntu.

lsb_release -d







So I tried

Get-WmiObject -Class Win32_OperatingSystem

Which by default returns (Not really what I was looking for)








After digging through the properties a little What I ended up using was

(Get-WmiObject -Class Win32_OperatingSystem).caption

This returns (Exactly what I was looking for)



I added this as an alias so I do not have to type this in every time.
I had to make the function first and then alias that, using the command
itself did not work (It was trying to assign the alias to the caption
string object).

Note: There may be an easier way to do this, I will update if I find it.

function fget_os {(Get-WmiObject -Class Win32_OperatingSystem).caption}

Set-Alias getos fget_os


Done :)