Friday, November 1, 2013

PowerShell One-Liners


PowerShell is Microsoft's shell for their product lines. It's now on version 3.0. If you miss the power of the command line while using Windows on either your laptop or servers, PowerShell provides that power.

Important concepts:

  • Almost all aspects of the Microsoft ecosystem are objects within an overarching structure. You query and manipulate this structure and its objects with PowerShell. This includes all aspects of SharePoint, Active Directory, and Exchange. 
  • This "object nature" means that PowerShell pipes pass objects and properties, not just text. 
  • Variables store data-structures of objects. 


Note: Unwrap the code lines before you use them.

Get Help

Get the usage of the command "Select-Object":

Get-Help Select-Object

Built-in examples for the command "Select-Object":

Get-Help Select-Object -examples | more

Get the list of all commands and sort it:

Get-Command | select-object name | sort name | more

Get the list of help topics for other parts of PowerShell:

Get-Help about*

Opening Files and Programs

PowerShell equivalent to Apple's Mac OS X command "open" is "Invoke-Item":

Start firefox.exe:

Invoke-Item "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"

Open the file "Document.pdf" that is located the current directory:

Invoke-Item Document.pdf

Invoke-Item "\\myserver\c\Files\Document.pdf"

Manage Processes

To pattern match on an object list, use "Where-Object". The current object being processed is referred to by the special variable "$_". Members are accessed via the "." operator.:

Get-Process | Where-Object {$_.processname -match "powershell" } | Select-Object processname,CPU,VM

Dump all properties for all processes, print the process name and the VM size, and then sort by VM size:

Get-Process | Select-Object processname,virtualmemorysize | sort virtualmemorysize

Find the busiest Google Chrome process:

Get-Process chrome* | Select-Object processname,ID,CPU | sort CPU

Store the list of process objects:

$ListOfProcessObjects = Get-Process

Print the process name and virtual memory size from the stored process objects and sort by virtual memory size:

$ListOfProcessObjects | Select-Object processname,VM | sort VM

Print the chrome processes and sort by virtual memory size:

$ListOfProcessObjects | Where-Object { $_.processname -match "chrome" } | select-object processname,VM | sort VM

Find the Google Chrome process with the largest VM size:

Get-Process chrome* | sort VM | Select-Object processname,ID,VM -last 1

Find the Google Chrome process with the smallest VM size:

Get-Process chrome* | sort VM | Select-Object processname,ID,VM -first 1

Stop all Chrome processes:

Stop-Process -processname chrome*

Working on file systems

Find all "exe" files in a tree, list their full path, and sort "fullname":

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.exe | select-object fullname | sort fullname | more

Find all mp3s and sort by ascending size:

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.mp3 | select-object fullname,length | sort length

Find all mkvs and sort by ascending lastaccesstime:

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.mkv | select-object fullname,lastaccesstime | sort lastaccesstime

To get a list of all of an objects properties, use Where-Object on the list of file system objects to get a single object, and then pipe the object to: Select-Object * | more

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.pdf | Where-Object { $_.fullname -match ".*Q1_Report.pdf" } | Select-Object * | more

Get pdfs that were last accessed by Windows in 2008, get their fullname, length, and last access time, then finally sort by length in ascending order:

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.pdf {$_.LastAccessTime -match "2008" } | Select-Object fullname,length,LastAccessTime | sort length

You can output a command to CSV with "Export-CSV". This command requires a filename as an argument:

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.pdf | Select-Object fullname,lastaccesstime,length | sort length | Export-Csv C:\Files\list.csv

Load the above results into the clipboard as a list:

Get-ChildItem 'C:\Tree\Of\Files\' -recurse -include *.pdf | Select-Object fullname,lastaccesstime,length | sort length | Format-list | clip

New directory:

New-Item c:\Files\Log_Data -type directory

New directory on a server:

New-Item \\myserver\c\Files\Log_Data -type directory

New empty file:

New-Item c:\Files\Log_Data\logoutput.txt -type file

Create a new file on a server:

New-Item \\myserver\c\Files\logoutput.txt -type file

Rename a file:

Rename-Item c:\Files\Log_Data\logoutput.txt

Rename a file on a server:

Rename-Item \\myserver\c\Files\logoutput.txt

Delete a file:

Remove-Item C:\Files\Log_Files\

Delete a file on a server:

Remove-Item \\myserver\c\Log_Files\logoutput.txt

Delete a directory:

Remove-Item C:\Files\Log_Files

Delete a directory on a server:

Remove-Item \\myserver\c\Log_Files

Write text to a file. This replaces the contents of the file:

set-content c:\Files\Log_Files\ -value "Line 1" + "Line 2" + "Line 3" + ....

Log Processing

Store list of log objects from the event log "System":

$SystemLogs = Get-EventLog System

Get all the log entries of entrytype "Error" from the stored system logs and then sort by "Message"

$SystemLogs | Where-Object {$_.entrytype -match "error" } | select-object message,entrytype | sort message | more

Get all the log entries of entrytype "Error" from the stored system logs and then return a sort list of unique log messages:

$SystemLogs | Where-Object {$_.entrytype -match "error" } | select-object message| sort message | more | Get-Unique -asstring | more

Get list of logging providers:

$ListOfProviders = get-winevent -listprovider *

Looking at Hotfixes

Get the IDs of all installed hotfixes and their install times and then sort by install time:

Get-HotFix | select-object hotfixid,installedon | sort installedon | more

Get the hotfix list from a remote machine (replace someservername with the name of a server in your environment). The account from which you run this needs admin rights to that machine:

Get-HotFix -computername someservername| Select-Object hotfixid,installedon | sort installedon | more

Using PowerShell on remote machines

Start an interactive PowerShell session on the remote computer myserver:

Enter-PsSession myserver

Stop an interactive PowerShell session:


Run a command on a list of remote machines:

Invoke-Command -computername myserver1, myserver2, myserver3 {get-Process}

Run a remote script on a list of remote machines:

Invoke-Command -computername myserver1,myserver2,myserver3 -filepath \\scriptserver\c\scripts\script.psl

Operate interactively on a list of machines by setting up a "session" of open connections:

$InteractiveSession = new-pssession -computername myserver1, myserver2, myserver3

Run a remote command on the new session. This runs it all the connections in the session:

Invoke-Command -session $InteractiveSession {Get-Process} 

Run the remote command on the session, but report only certain objects:

invoke-command -session $InteractiveSession {Get-Process | select-object name,VM,CPU }

Groups and Users

Get all of the user objects in "Data-Center-Team"

Get-ADGroupMember -Identity “Data-Center-Team”

Suppose the group IT-Team contains the group "Data-Center-Team" and other teams. To list the groups in "IT-Team":

Get-ADGroupMember -Identity “IT-Team”

To list the groups in "IT-Team" and all of those groups' members:

Get-ADGroupMember -Identity “IT-Team” -Recursive

Add user "thomasd" to the Data-Center-Team group:

Add-ADGroupMember -Identity “Data-Center-Team” -Members "thomasd"

Remove user "thomasd" from the "Data-Center-Team" group:

Remove-ADGroupMember -Identity “Group-A” -Members "thomasd"

Add the members of "London-Office" group to the "IT-Group" group:

Get-ADGroupMember -Identity “London-Office” -Recursive | Get-ADUser | ForEach-Object {Add-ADGroupMember -Identity “IT-Group” -Members $_}

Remove the members of the "London-Office" group from the "IT-Group" group:

Get-ADGroupMember -Identity “London-Office” -Recursive | Get-ADUser | ForEach-Object {Add-Remove-ADGroupMember “IT-Group” -Members $_}

Get all of the user objects in groups beginning with "Development-":

Get-ADGroup -LDAPFilter “(name=Development-*)” | Get-ADGroupMember | Get-ADUser

Get all of the users in groups beginning with "Development-" that are disabled:

Get-ADGroup -LDAPFilter “(name=Development-*)” | Get-ADGroupMember | Get-ADUser | Where-Object {$_.Enabled -eq $False }

Find all of the users in groups beginning with "Development-" that are disabled and add them to the "Development-Disabled" group:

Get-ADGroup -LDAPFilter “(name=Development-*)” | Get-ADGroupMember | Get-ADUser | Where-Object {$.Enabled -eq $False} | ForEach-Object { Add-ADGroupMember -Identity “Development-Disabled” -Members $_ -Confirm:$False }

Get all members of all groups with their enabled status and put them in a CSV file in C:\Files\ :

Get-ADGroup -LDAPFilter “(name=Development-*)” | Get-ADGroupMember | Get-ADUser | Select-Object Enabled,SamAccountName | sort Enabled | Export-Csv C:\Files\Development-Group-Users.csv


Reset your network connections:

"release", "renew", "flushdns" | %{ipconfig /$_}
Get a list of the domain controllers in your domain:

[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() | Select-Object DomainControllers

-Adam (a0f29b982)