PowerShell Bible.txt - Notepad

PowerShell Bible

How to display general info about a computer:

get-wmiobject -class win32_computersystem

Domain :
Manufacturer :
Model :
Name :
PrimaryOwnerName :
TotalPhysicalMemory :

Get PowerShell version info



List all processes:

List all processes and sort by CPU:
get-process | sort CPU

Show the top 5 CPU consuming processes:
get-process | sort CPU | select -last 5


Stop a process by process id number:
stop-process pid_number

Stop a process by name:
stop-process - name processname


Shows the available amount of RAM.
Get-Counter '\Memory\Available MBytes'

Shows a continually updating record of the current CPU utilisation.
Get-Counter -counter "\processor(_total)\% processor time" -continuous

Similar to the above command except it only displays the CPU utilisation three times with a sample interval of two seconds. Note, as with all counters, it can be used with the 'computername' parameter to target remote PCs.
Get-Counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 2 -MaxSamples 3 -computername 55cv12s

Shows the percentage of free disk space.
Get-Counter -Counter "\LogicalDisk(_Total)\% Free Space"

How to clear the screen in powershell


Show Disk Utilisation

Shows the disk utilisation of all drives:

Get-WMIObject Win32_LogicalDisk | Select SystemName,DeviceID,VolumeName,@{Name="size(GB)";Expression={"{0:N1}" -f($_.size/1gb)}},@{Name="freespace GB)";Expression={"{0:N1}" -f($_.freespace/1gb)}}

Sample Output

SystemName : 3JSPD2S
DeviceID : C:
VolumeName : System
size(GB) : 465.8
freespace GB) : 383.9

If you don't want to see network and USB drives use:

Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" | Select SystemName,DeviceID,VolumeName,@{Name="size(GB)"; Expression={"{0:N1}" -f($_.size/1gb)}},@{Name="freespace(GB)";Expression={"{0:N1}" -f($_.freespace/1gb)}}

The following command allows you to view disk usage information for a list of hosts.

Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" -computer (Get-Content c:\computers.txt) | Select SystemName,DeviceID,VolumeName,@{Name="size(GB)"; Expression={"{0:N1}" -f($_.size/1gb)}},@{Name="freespace(GB)";Expression={"{0:N1}" -f($_.freespace/1gb)}}

Here is an example of a c:\computers.txt file:
server1 [hit enter key]
laptop2 [hit enter key]
Desktop1 [hit enter key]

Installing and enabling Telnet Server

First, install the Telnet service
install-windowsfeature "telnet-server"

View the status of your Telnet service:
get-service telnet

Before you can start the service you need to enable it. In this example we set it to startup automatically.
set-service tlntsvr -startup "automatic"

Now we can start the Telnet service
start-service telnet

Note: Telnet users need to be added to the 'TelnetClients' group in order to use Telnet.

How to rename your computer using PowerShell

Run the below command to change your computer name. Note, your computer name won't change until you restart.

Rename-Computer -NewName "Windows8"

How to launch a program from PowerShell

Type '& /path_to_program/program.exe' eg:

& "C:\Program Files\Internet Explorer\iexplore.exe"

How to execute powershell scripts

In Windows Server 2012 there is a default execution policy setting that prevents you from running external/custom powershell scripts (.ps1). Type either of the below commands to remove this restriction.

Allows you to run locally created scripts: Set-ExecutionPolicy RemoteSigned
Allows you to also run scripts downloaded from the web: Set-ExecutionPolicy Unrestricted

To view you current execution policy type:

For more info on execution policy type:
help about_execution_policy

Powershell equivalent to the 'find' command

Use 'select-string' eg:
get-content C:\hi.txt | Select-String "world"

How to rename a file in powershell

ren C:\old_name.txt c:\new_name.txt

Powershell equivalent to ipconfig

List interfaces configured with IPv4 addresses:
Get-NetIPAddress -AddressFamily IPv4

Modify properties of an existing IP address:
Set-NetIPAddress -InterfaceIndex 12 -IPAddress

Create a new IP address:
new-NetIPAddress -InterfaceIndex 12 -IPAddress

PowerShell Help

To download the help files from the Microsoft website over the Internet type:

The above can only be performed once every 24 hrs. To force the update right now type:
update-help -force

To save your help file locally:
save-help c:\destination

You can download the help file from a local source:
update-help -sourcepath

The below examples show you to read help files on an example cmdlet, get-service.

Shows all help info:
help get-service -full

Only shows the examples:
help get-service -example

Show help in a new window:
help get-service -showwindow

Opens the help in Internet Explorer from an online source:
help get-service -online

Using 'get-command' to identify cmdlets and functions based on '-verb' and '-noun'

The below command will list all cmdlets and functions:

Commands are broken down as verbs (actions) and nouns (things), eg 'get-command', get=verb and command=noun.

List commands that include printer (noun):
get-command -noun *printer*

List commands that begin with 'add' (verb):
get-command -verb add*

You can also search for particular commands, for example if you are looking for GPO related cmdlets:
get-command | select-string gpo

How to view an event log

Type 'get-eventlog' and then specify the name of the log eg security. The information doesn't display well in powershell. Export it to a csv file and then import it into powershell to view all details:

get-eventlog Security | export-csv -path c:\sample.csv

import-csv -path C:\sample.csv

Using 'show-command' to help you type commands

You can type the below to launch a GUI to assist you in creating a command such as 'new-aduser'. After you have completed using the GUI you can copy the contents of the command and paste it in powershell.

show-command get-aduser

'whatif' and 'confirm'

These parameters can be added to the end of commands to provide the below functionality

new-aduser -name bob -whatif - won't actually run the command, but will show you what the command would have done.

new-aduser -name bob -confirm - will prompt you to confirm before actually executing the command.

How to create a 'file' or 'directory' from the command line

Create a file:
new-item -path c:\ -type file -name hi.txt -value "Hello World"

Create a directory:
new-item -path c:\ -type directory -name hello_world_folder

Providers - an adapter between storage and the shell

List powershell providers:

List drives in the current session:

You can map a drive with new-psdrive. This is like the old 'net use' command. The below command maps c:\appdata to the x: drive. You can add -persist to make the drive statically mapped.
New-PSDrive -Name x -PSProvider filesystem -Root C:\AppData\

Listing folder contents


'get-item' and modes

You can use get-item to show similar information as 'get-childitem', but you can contain it to an individual directory or file.

The output of 'get-item' lists a Mode section, this is explained below:

d - Directory
a - Archive
r - Read-only
h - Hidden
s - System

How to list the contents of a file

The below command prints the contents of a file to the screen. You can also use 'cat':
get-content C:\hi.txt

Opening a file with notepad from powershell

notepad c:\sample.txt

Exporting output to .csv and .xml files

Export the output of get-process to a csv file:
get-process | export-csv -path c:\sample.csv

Export the output of get-process to an xml file:
get-service | export-clixml -path c:\services.xml

Comparing the difference between two objects

In the below example, we have a csv file holding the contents of a previous 'get-process' command. We are comparing the difference between this file and a current 'get-process' command.

compare-object -referenceobject (import-csv x:\process.csv) -differenceobject (get-process) -property name

The ouput of the command will display the difference between the two outputs eg any processes that have started since the creation of x:\process.csv.

The below command uses the -includeequal parameter to compare two text files and mark objects that exist in both files with a = symbol.

compare-object -referenceobject (get-content h:\h_drives.txt) -differenceobject (get-content h:\separated_staff.txt) -includeequal | export-csv h:\separated_staff_with_a_h_drive.csv

Importing a .csv file

import-csv -path C:\process.csv

Using 'out-file' to export output to standard text

'out-file' retains formatting.
get-service | out-file -filepath x:\sample.txt

Exporting output to gridview

Gridview allows you to apply filters to output. It displays the output in a new GUI window.
get-service | out-gridview

Converting output to a HTML file

get-service | convertto-html | out-file -filepath c:\sample.html


Modules such as Active Directory and Exchange can be added into PowerShell. They can then be manipulated using PowerShell commands.

To list the available modules:
get-module -listavailable

To add a module such as AD
import-module activedirectory

You can view all commands for the module
get-command -module activedirectory

List aliases for a command

You can use 'get-alias' to list shortcuts for commands. Eg gsv = get-service.
get-alias -definition get-service

How to list installed programs on a remote PC

The below command lists all installed programs on a remote machine named 1kcb92s. If you don't include the -computername parameter it will show software installed on your local computer.
Get-WmiObject -class win32_product -computername 1kcb92s

You can try to return particular results by pipeing the output through select-string:
Get-WmiObject -class win32_product -computername 1kcb92s | select-string "Visio"

How to determine if a CPU is 32 or 64 bit architecture

Get-WmiObject -class "Win32_Processor" | select-object "AddressWidth"

If the AddressWidth is "32" then you're on a 32-bit operating system.
If the AddressWidth is "64" then you're on a 64-bit operating system.

Another way is:
get-wmiobject -class win32_operatingsystem | select-object -property "osarchitecture"

Lists users in a group and export the results to a csv file

The below command lists all members of the group "insert group name" and extracts the "givenname" and "surname" properties. It then extracts the data to a csv file.
get-adgroupmember "insert group name" | get-aduser | select-object -property "givenname", "surname" | export-csv "C:\stuff\members.csv"

To combine the columns "givenname" and "surname" with Excel you can create a new column with the below formula. This formula assumes that "givenname" is in column A and "surname" is in column B.
=A1&" "&B1

List all groups that a user or computer is a member of

Add the relevant username in place of "insert_username"
(get-aduser -identity insert_username -properties MemberOf | select-object MemberOf).MemberOf

A simpler and more concise way to display AD group membership for a username or computername is:
Get-ADPrincipalGroupMembership -identity username/computername | select-object -property "name"

If you are having trouble getting the above command to work with a computername, try:
Get-ADComputer -identity computername | Get-ADPrincipalGroupMembership | select-object -property "name"

Using Get-Member to view all properties of a class

Lets say you want to extract information from your system using get-wmiobject. The below command will get information about some properties from the win32_operating system class such as organization and buildnumber.
get-wmiobject -class win32_operatingsystem

To see all properties available to the WMI class, win32_operatingsystem, use get-member.
get-wmiobject -class win32_operatingsystem | Get-Member

Now lets say you want to grab the ProductType property. You can use the format-table command to extract this property
get-wmiobject -class win32_operatingsystem | Format-Table -Property producttype

Using Test-Connection to ping several computers

The below script allows you to ping several computers and store the results in a text file. It will list the hostname and whether or not it was pingable. This single column can easily be split into two in Excel using the 'text to column' feature and by selecting space as a deliminator.

get-content h:\names.txt | foreach { if (test-connection $_ -quiet) { write-output "$_ pingable" | out-file h:\results.txt -append } else { write-output "$_ down" | out-file h:\results.txt -append}}

How to print from powershell

The below command prints the phrase "hello world" on a network printer called 'printer'
"hello world" | out-printer -name "\\print_server\printer"

Finding inactive computer objects in Active Directory

The below command returns all Windows XP machines along with their "passwordlastset" property. The "passwordlastset" property refers to a computer password that is renewed every 30 days. If a computer has a "passwordlastset" date older than 30 days ago it is likely that the machine is no longer in use on the domain and can be deleted from Active Directory.

get-adcomputer -filter {operatingsystem -eq "Windows XP Professional"} -property * | select-object "name","operatingsystem", "passwordlastset" | sort-object -property "passwordlastset" | export-csv -path "C:\stuff\xp_machines.csv"

Creating and using restore points

To create a restore point with a description of "Test restore point" type:
checkpoint-computer -description "Test restore point"

The below command lists all of the restore points on the computer.

The following command allows you to restore you computer using a restore point. In this case restore point 253. You can clarify the ID number of a restore point by using get-computerrestorepoint.
restore-computer -RestorePoint 253

Show the last user logon date for a computer

'lastlogon' is updated reasonably regularly and indicates the last time a user logged onto the machine.
Get-ADcomputer -identity hostname -properties Name,LastLogon | Select-Object Name,@{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}

Find a computer's last boot time

get-wmiobject -class win32_operatingsystem -computername hostname | select name,@{l='lastboottime';e={$_.converttodatetime($_.lastbootuptime)}}

Show the username of whoever is currently logged onto a computer

get-wmiobject -computername hostname -class win32_computersystem -property * | select-object username,name

The below command does the same as the above, but with a list of PCs contained within a file named computer_names.txt. It also exports the result to a CSV file.
get-wmiobject -computername (get-content c:\computer_names.txt) -class win32_computersystem -property name,username | select-object username,name | export-csv c:\results.csv

Identifying unused/old AD user accounts

The 'lastlogondate' is a useful property for identifying unused AD user accounts using the Get-ADUser cmdlet. A user's lastlogontimestamp value gets updated once every 12 days or so, no matter how often that user logs on during that time period.

get-aduser -filter * -property displayname,samaccountname,lastlogondate | select-object -property displayname, samaccountname,lastlogondate | export-csv h:\old_ad_accounts.csv

How to display all AD user accounts in a particular OU

Use the -searchbase parameter and specify the OU. You can locate the appropriate identifer for the OU by right clicking on the OU in 'AD User and Computers' and selecting properties. Make sure you have 'Advanced Features' ticked under 'View' on the toolbar. Click the 'Attribute Editor' tab and look for the 'distinguishedname' attribute.

get-aduser -searchbase "OU=Staff,OU=BHP,DC=biliton,DC=corporate" -filter * -property "displayname","samaccountname","canonicalname"

How to run Get-ADUser against a list of users

You can simply pipe the contents of the file into the Get-ADUser cmdlet. It will run the command against each user in the file. The below command pipes a list of usernames into get-aduser and converts each of them into the fullname of the user.

get-content h:\username.txt | get-aduser -property "displayname" | select-object -property "displayname"

How to obtain the model number of a PC and the total amount of RAM

The win32_computersystem contains a lot of useful information such as a PC's model number and total physical memory. The below commands reads a list of PCs as input to the get-wmiobject cmdlet. It selects each machines name, model, currently logged on user, total physical memory (including conversion from bytes to Gb) and exports the result to a CSV file.

get-wmiobject -class win32_computersystem -computername (get-content c:\computer_names.txt) -property * | select-object -property "__server","model","username",@{label="totalphysicalmemory";expression={[int]($_.totalphysicalmemory/1gb)}} | export-csv "c:\results.csv"

How to use Get_ADUser to determine if a user has an active mailbox

An AD user account with a deleted mailbox can still have an email address property listed in AD. However, the 'msexchmailboxguid' is only displayed for users who have a mailbox. If a user's mailbox has been removed then they will no longer have a 'msexchmailboxguid'. This property is a useful way to determine if a user has a mailbox, without using the Exchange Management Module.

get-aduser -identity username -property * | select-object -property "emailaddress", "msexchmailboxguid", "name", "displayname"

How to display a PC's serial number and BIOS version

Use the WMI win32_bios class.
get-wmiobject -class win32_bios -computername hostname

Display AD group membership for a list of users

The below command takes a list of usernames and returns the AD group membership of each user. Note, the = and ^ symbols are for display purposes only and make the information easier to read.

$users = get-content "h:\users.txt" ; foreach ($user in $users) {($user | Get-ADPrincipalGroupMembership | select-object -property "name") + "==========================" + "^$user^" + "=========================="}

Display AD group membership for a list of computers

The below command takes a list of computer names and returns the AD group membership of each computer. Note, the = and ^ symbols are for display purposes only and make the information easier to read.

$computers = get-content "h:\computers.txt" ; foreach ($computer in $computers) {($computer | Get-ADComputer | Get-ADPrincipalGroupMembership | select-object -property "name") + "==========================" + "^$computer^" + "=========================="}

Filtering get-wmiobject searches

Use the - filter parameter with ' name like' to refine your result. The % symbol can be used as a wildcard. * is not accepted. The below command will output the computer name (__SERVER) plus any software product name (name) that begins in ' Microsoft Office' .

get-wmiobject -class win32_product -filter "name like 'Microsoft Office%'" | select-object "__SERVER", "name"

Using Set-ADUser and Move-ADObject

The below PowerShell command reads a text file of AD user accounts (ObjectGUIDs). It moves each user into a new OU as indicated by the distinguished name in the targetpath parameter.

get-content c:\objectguids.txt | move-adobject -targetpath "OU=Contractors,OU=Users,OU=BHP,DC=Biliton,DC=Corporate"

The below PowerShell command edits the company field (AD user object attribute) for all users listed in a text file (ObjectGUIDs).

get-content c:\objectguids_CGI.txt | set-aduser -Replace @{company='CGI'}

The difference between Disabling and Removing an Exchange mailbox in Exchange 2007/2010

In the Exchange Management Console when a mailbox is selected the actions pane shows two tasks; Disable and Remove.

Disable will remove the Exchange attributes for the user account but leave the user account in Active Directory. The mailbox is then also left in the Exchange mailbox database until the retention period has lapsed (30 days), then it is removed permanently.

Remove will remove both the Exchange mailbox and the user account from Active Directory

Disable is the safest option, because you can quickly reconnect the mailbox to the user again if it is still within the retention period of 30 days.

PowerShell Exchange mailbox commands

Enable-Mailbox is for creating a mailbox for an existing user, and Disable-Mailbox removes only the Exchange attributes from the user account

New-Mailbox is for creating a new AD user and mailbox at the same time, and Remove-Mailbox removes both the mailbox and the user object.

How to recursively delete a list of folders and their contents

The below command reads directory paths in a file and deletes each path including all child files and folders.

remove-item (get-content h:\folders.txt) -recurse

How to move folders to a new location

The below command reads a text file of directory paths and moves the folders to a new directory called h:\newfolder.

move-item -path (get-content h:\folders.txt) -destination h:\newfolder

How to install the Active Directory module on Win7

Download "Remote Server Administration Tools" on Win 7 [KB958830]
Then add the Window features: Remote Server Administration Tools > Role Administration Tools > AD DS and AD LDS Tools > Active Directory Module for Windows PowerShell.

Display the expiration date for users in a specific OU

get-aduser -searchbase "OU=Contractors,OU=Users,OU=billiton,DC=bhp,DC=corporate" -filter * -searchscope "base" -property accountexpirationdate | select-object -property samaccountname,accountexpirationdate

Note the -searchscope parameter. This refers to the OU search depth.
Base or 0 = Search only the current path or object.
OneLevel or 1 = Search the immediate children
Subtree or 2 = Search the current path/object and all children

Set the expiration date for AD user objects

Compile the samaccountnames for the user accounts in a text file and run the below command to set the same expiry date for each account.
get-content C:\stuff\expire.txt | set-adaccountexpiration -datetime "24/12/2016"

Remove a list of AD Computer Objects

Compile the samaccountnames for the computer accounts in a text file and run the below command to delete each one from AD.
get-content C:\stuff\computer_deletions.txt | remove-adcomputer

Note, you can add -Confirm:$false to the end of the above command to prevent confirmation prompts.

How to backup an Exchange 2010 mailbox to a pst file

Step 1 - Grant User Rights for Mailbox Exports in Exchange 2010 SP1
The first step is to grant an account the right to export mailboxes. In the Exchange Management Shell run the following command. Afterwards, close and re-open the Exchange Mgt Console otherwise you won't have permission to perform step 3.

New-ManagementRoleAssignment -Role "Mailbox Import Export" -User Administrator

Step 2 - Create a Network Share for Mailbox Exports in Exchange 2010 SP1
Next we need to create the network share that will be used as the file path for the exported PST files. All that is required here is a network share that the Exchange Trusted Subsystem group has read/write permission to.

Step 3 - Export a Mailbox with an Exchange Server SP1 Mailbox Export Request
Use New-MailboxExportRequest to start the mailbox export. The only two required parameters for the command are the file path to the export PST file, and the name of the mailbox to export.

New-MailboxExportRequest -Mailbox test.user -FilePath \\shared_folder\pst\mailbox.pst

To view the progress of your mailbox export use the below command.


Note, the Microsoft Exchange Mailbox Replication service needs to be running in order to be able to export mailboxes. If this service does not start it may be that the Net TCP Port sharing service is disabled. You can set this service to start automatically with the below command.

Set-Service NetTcpPortSharing -StartupType Automatic

Send an email using the send-mailmessage cmdlet

The send-mailmessage cmdlet allows you to script the delivery of email. In the below example I have attached two text files using the -attachment parameter. I have also output a variable into the body of the email. Note, the variable needs to be a string eg $variable = get-content c:\stuff\file.txt | out-string

send-mailmessage -to "Graham <graham@domain.com>" -from "nick <nick@domain.com>" -subject "test mail" -smtpserver mail.domain.com -attachment "c:\stuff\file.txt","c:\stuff\file2.txt" -body $variable

How to run a powershell script as a scheduled task in Windows Server 2008 R2 and older versions

Set the action part of the scheduled task to run a script and browse to a bat file. Within the bat file call your powershell script. For example:
powershell -file c:\monitoring.ps1

The Server Manager PowerShell Module

The Server Manager Module can be used to install and remove Windows Features. To add the module type:
Import-Module servermanager

This module exports 3 cmdlets:

Using remove-item to remove multiple files

You can specify multiple files in the same command:
remove-item -path "c:\folder1\file1.txt","c:\folder2\file2.txt"

Searching for files of a particular file type

Use the get-childitem cmdlet with a filter of "*file extension*" to find files with a particular file extension. The below example will list pst files from a particular directory if they exist.

get-childitem -path '\\hostname\c$\stuff' -recurse -filter "*.pst"

Displaying environment variables

The below command lists all current environment variables:
get-childitem env:

You can display a particular environment variable if required eg the username variable.
get-childitem env:username

Displays only the username value:
(get-childitem env:username).value

Copying a folder using the copy-item cmdlet

copy-item -path \\hostname\c$\source_folder -recurse -destination \\hostname2\c$\destination_folder

Note, the recurse parameter is necessary if you want to include child folders/files.

Restarting and powering off your PC

The stop-computer and restart-computer cmdlets can be used to poweroff and restart your computer.

Logging of PowerShell activity and the Common Parameter, Verbose

Use the start-transcript cmdlet to begin the capture. You can specify where you want the transcript saved (.txt file) using the - path parameter.

Use the stop-transcript cmdlet to end the capture.

The - verbose parameter can be specified with all cmlets. It' s useful if you want to see activities that are not normally displayed eg when used with the remove-item cmdlet, verbose will display each file that is removed.

Allow a non-privileged user to run a scheduled task that runs a batch file

The user will need to have "Log on as a batch job" rights on the computer that hosts the script. This can be configured on the local security policy of the host computer.

You can change the policy on the host under:
Administrative Tools -> Local Security Policy -> Local Policies -> User Rights Assignment -> Log On As Batch Job
Simply add the user under the Local Security Setting.

List all WMI classes under the root\cimv2 WMI namespace

Get-wmiobject - list

Prerequisites for the Windows PowerShell AD module

You will need to install the below KB for Win7 machines.

You will also need to enable the below features, can be done via DISM.

dism /online /enable-feature /featurename:RemoteServerAdministrationTools
dism /online /enable-feature /featurename:RemoteServerAdministrationTools-Roles
dism /online /enable-feature /featurename:RemoteServerAdministrationTools-Roles-AD
dism /online /enable-feature /featurename:RemoteServerAdministrationTools-Roles-AD-Powershell

Backing up and restoring Group Policy

First, import the group policy powershell module.
Import-Module -Name grouppolicy

The below command will backup all GPO from a DC.
Backup-GPO -All -Path \\servername\backups -Comment "weekly Backup" -Domain nickbeare.com -Server dc1

Run the below command to restore the GPO on the server:
Restore-GPO -All -Domain nickbeare.com -path \\servername\backups

Change the size and colour of a PowerShell window

Append the below to the top of your script. Note you need to run clear-host at the end to clear up the formatting.

$a = (Get-Host).UI.RawUI
$a.WindowTitle = "Insert Title Name"
$a.BackgroundColor = "green"
$a.ForegroundColor = "yellow"
$b.Width = 40
$b.Height = 10
$a.WindowSize = $b

Cmdlet for searching for disabled AD accounts

Search-ADAccount -accountdisabled

Disable of list of AD user accounts

get-content c:\usernames.txt | disable-adaccount

Changing folder permissions using powershell

The below command lists permissions for a folder. You can use set-acl to change the permissions.
get-acl -path c:\stuff | format-list

Enable a user's mailbox

Add the Exchange Mgt shell:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin

Enable the mailbox for the user:
enable-mailbox -identity username

Specify the database that mailbox is stored on, eg:
Database: EXCHANGE_SERVER\Storage Group 3\Mail Store DB3

Exchange 2007 SP3 Prerequisites on Windows Server 2008 R2

The below command installs the prerequisites for Hub , CAS , Mailbox - Typical Installation.
Import-Module ServerManager
Add-WindowsFeature RSAT-ADDS,Web-Server,Web-Metabase,Web-Lgcy-Mgmt-Console,Web-Dyn-Compression,Web-Windows-Auth,Web-Basic-Auth,Web-Digest-Auth,RPC-Over-HTTP-Proxy

You can also install features using the cmd prompt, eg:
ServerManagerCmd -i RSAT-ADDS

Get OS name from a computer

Get-WmiObject -class win32_operatingsystem -property * | select-object caption,__server

Show installed Windows Updates (KBs) on a computer

Get-WmiObject -Class Win32_QuickFixEngineering -ComputerName hostname

Show all local profiles on the target computer

Get-WmiObject - computername 2hspd2s -class win32_userprofile -property * | select-object localpath,sid

Delete profile with localpath like ptargetuser

Get-WmiObject -class win32_userprofile -filter "localpath like '%ptargetuser'" | Remove-WmiObject

How to remove a list of users from an AD group

Note, the -confirm:$false part just prevents confirmation messages from appearing.
Remove-ADGroupMember -identity insert_group_name -member (get-content C:\users_to_remove.txt) -confirm:$false

PowerShell remoting

Enable ps-remote:

Disable ps-remote:

Establish a remote connection with a PC:
Enter-PSSession -computername jfspd2s

Show ps-remote privileges:
Get-PSSessionConfiguration | select-object -expandproperty permission

Enable ps-remote via PsExec:
C:\Pstools\PsExec.exe \\computername -s powershell Enable-PSRemoting -Force

Show all output for a property

select-object -expandproperty value

Using Where to filter results

get-service | Where-Object { $_.status .match "running" }
get-service | where-object {$_.Status -eq "Stopped"}

Using sort-object to sort results

Sorts in ascending order by default.
Sort-Object -descending -property "value"

Convert string to lower or upper case

Convert to lowercase:
$lowercase_string = $convert_me.ToLower()

Convert to uppercase:
$uppercase_string = $convert_me.ToUpper()

Removing and adding users to a group

To move the current membership of one group to another, follow the below steps:

Get the current group membership of group1:
get-adgroupmember group1 | select-object name | out-file C:\users\beare\users.txt

Assign the group members of group1 to a variable named members. Note, you may need to remove any unecessary headings from users.txt before assigning the output to the members variable.
$members = get-content C:\users\beare\users.txt

Add the members to group2:
add-adgroupmember -identity group2 -members $members

Remove the group members from group1:
Remove-ADGroupMember -identity group1 -members $members

Remotely execute a GPO update on a PC

invoke-gpupdate -force -computer remotecomputername

Moving multiple accounts to another OU and disabling them

Affected SAMAccountNames are recorded in disabled_userids.txt.

Output the displaynames of the affected users for record purposes:
get-content c:\users\disabled_userids.txt | get-aduser -property "displayname" | select-object -property "displayname", "samaccountname" | Out-File C:\Users\display_names.txt

Obtain the GUIDs for the affected users:
get-content c:\users\disabled_users.txt | get-aduser -property "objectguid" | select-object -property "objectguid" | Out-File C:\Users\guids.txt

Move the affected users to the DisabledUsers OU:
get-content c:\users\guids.txt | move-adobject -targetpath "OU=DisabledUsers,OU=Project,DC=business,DC=gov,DC=au"

Set the description field of each affected user as the relevant reference number:
get-content c:\users\guids.txt | set-aduser -Replace @{description='Reference_Number'}

Disable the accounts:
get-content c:\users\guids.txt | Disable-ADAccount

Close all processes relating to a particular program

The below line will close all active Internet Explorer processes:
Get-Process -name iexplore | stop-process

The below line will close all active Notepad processes. Can be useful when you have many instances of the program open and it would take a while to close them all via the GUI.
Get-Process -name notepad | stop-process

How to view and clear AD attributes

The below command takes a list of samaccountnames and displays the 'manager' for each one:
get-content c:\stuff\users.txt | Get-ADUser -property manager | Select-Object -Property manager

The below command clears the 'manager' attribute for each samaccountname in users.txt: get-content c:\stuff\users.txt | set-aduser -clear manager

Set a particular OU as your search base

The below command searches the separated staff OU and outputs the samaccountname and manager for each object in the OU:
get-aduser -searchbase "OU=Separated Staff,OU=BHP,DC=Billiton,DC=corporate" -filter * -property manager | select-object -property samaccountname,manager

Run Windows Server 2012 in non-GUI mode

Use the following command to view a list of the current Server GUI components running:
Get-WindowsFeature server-gui*

Give your attention to the Name column. You use this value with the Remove-WindowsFeature and Install-WindowsFeature PowerShell cmdlets.

To remove the server graphical shell, which reduces the GUI server installation to a Minimal Server Interface installation, run:
Remove-WindowsFeature Server-Gui-Shell

To remove the Graphical Management Tools and Infrastructure, which further reduces a Minimal Server Interface installation to a Server Core installation:
Remove-WindowsFeature Server-Gui-Mgmt-Infra

To remove the Graphical Management Tools and Infrastructure and the Server Graphical Shell, run:
Remove-WindowsFeature Server-Gui-Shell,Server-Gui-Mgmt-Infra

To re-add the full GUI mode you can use the below. Just ensure your source is correct:
Install-WindowsFeature server-gui-mgmt-infra,server-gui-shell -source:wim:d:\sources\install.wim:4

Show motherboard and CPU info

Get-WmiObject Win32_Processor

get-WmiObject -class Win32_Baseboard

Enable PowerShell Web Access

PSWA is a feature in Windows Server 2012 that turns a machine into a PowerShell gateway over https. To install:

Open Server Manager and add the IIS role and Windows PowerShell Web Access feature (requires .NET framework 4.5 feature).

Open an elevated PowerShell terminal and type the below command to create the PSWA page in ISS.

To give users permission to use PSWA run the below command in PowerShell. I found that the user needed to be in the local admin group to log into PSWA.
Add-PswaAuthorizationRule -UserName domain(or hostname)\username -ComputerName hostname -ConfigurationName microsoft.powershell

PSWA runs over HTTPS so you need to Create a self-signed certificate by:
Opening IIS 8, click on your server name, double click Server Certificates, click create self-signed certificate. Name the certificate and select personal.

Next you need to bind the certificate to the PSWA webpage:
Click on the default website and select bindings. Add a type of https, set IP address to All Unassigned, enter your port, leave hostname blank, don't check the require server name indication checkbox, and select the personal certificate you just created. You can select a non-standard port number if you like, but you will need to create an inbound firewall rule to allow the traffic.

I have found that you need to run the below PowerShell command otherwise you get an error when logging into PSWA - "Windows PowerShell remote management has been disabled on the destination computer"
Enable-PSRemoting -force

Accessing PSWA:
Go to https://yoursite/pswa and log in. Your username should be in the domain\user format.

Export a mailbox to a pst file

Create a bat file with the below contents and execute it to backup your mailbox to a pst file (includes mailbox, contacts, calendar etc). Also cleans up any completed mailbox export requests.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; $dated = get-date -f ssddMMyyyy; $mailbox = $dated + 'username.pst'; New-MailboxExportRequest -Mailbox username -FilePath \\hostname\shared_folder\$mailbox; Get-MailboxExportRequest -status completed | Remove-MailboxExportRequest -confirm:$false

Monitoring login attempts

The below event IDs appear in the security event log and are useful for monitoring login attempts:
4625 An account failed to log on.
4624 An account was successfully logged on.
4634 An account was logged off

Use get-eventlog to look for these events. Note, the parameter instanceID is the event ID. The below command returns all failed logon attempts:
Get-EventLog -LogName Security -InstanceId 4625

From this output you can drill down into one of the events by referencing the index (event ID):
Get-EventLog -LogName Security -Index 4258789

To get further information about the event from its message property you can run the below:
(Get-EventLog -LogName Security -Index 4258789).message

$event = Get-EventLog -LogName Security -Index 4258789

Monitoring RDP sessions

You can run either of the below commands to view the RDP event log:
Get-WinEvent -Path 'C:\Windows\System32\winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx'

Get-WinEvent -ProviderName "Microsoft-Windows-TerminalServices-LocalSessionManager"

Event IDs explained:
21 = Remote Desktop Services: Session logon succeeded:
24 = Remote Desktop Services: Session has been disconnected:
25 = Remote Desktop Services: Session reconnection succeeded:
23 = Remote Desktop Services: Session logoff succeeded:

Show successful RDP logons:
Get-WinEvent -logname "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" | where {($_.Id -eq "21")}

PowerShell equivalents to Unix Head and Tail

The below commands passed the output of a log to select-object and only returns the first 10 rows (most recent log entries):
Get-EventLog -LogName Security -InstanceId 4625 | select-object -First 10

The below command accepts the same input but returns the last 10 lines (oldest log entries):
Get-EventLog -LogName Security -InstanceId 4625 | select-object -last 10

Show the current CPU temperature in degrees Celsius

Generally, a high temperature for an AMD CPU is considered to be around 60 degrees Celsius, while an Intel CPU is considered to be hot around 70.

$temp = (Get-WmiObject -class "MSAcpi_ThermalZoneTemperature" -Namespace "root\WMI").currenttemperature ; $temp2 = ($temp - 2732) / 10.0 ; $temp2

Show remaining battery life in a motherboards BIOS battery

Get-WMIObject Win32_Battery -property EstimatedChargeRemaining

How to run gpupdate and gpresult on a remote computer

Invoke-Command -Computer hostname { gpupdate /force }

gpresult -r /scope:computer /s hostname /user username

Show the status of specific services on multiple PCs

Add each hostname to a new line in C:\hostnames.txt. Replace service1 and 2 with the relevant ProcessName.

$computers = Get-Content C:\hostnames.txt
get-service -Name service1, service2 -computername $computers | Select-Object displayname,status,machinename | sort displayname | Format-Table -autosize

Using the filter parameter

You can use the filter parameter with some cmdlets to filter your output. For example lets say we want to only find AD users who have the word *cgi* in their description property. We can use like.
Get-ADUser -Filter "description -like '*cgi*'"

You can also find exact matches using eq.
Get-ADUser -Filter "samaccountname -eq 'pbearen'"

Show the Outlook Web App status for all mailbox users (enabled/disabled)

Get-CASMailbox | ft DisplayName, OWAEnabled | out-file c:\owa.txt

Show uptime for multiple systems

The below command shows the uptime for a list of computer names in machine.txt.

Get-WmiObject -computername (get-content c:\users\machine.txt) -class win32_operatingsystem | select-object -property csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}

List active domain controllers in your domain

get-adgroupmember -Identity "domain controllers" | select-object -Property name

Install .NET Framework 3.5

Install-WindowsFeature Net-Framework-Core -source \\network\share\sxs

To verify installation, run the following command:

Recursively list the permissions for a folder and its children

get-childitem -recurse c:\parent_folder | Get-Acl | Format-List -property path, owner, accesstostring

List all installed software alphabetically

Get-WmiObject -class win32_product | Select-Object -Property name | Sort-Object -property name

Give a user or group full permission over all Group Policy Objects in the domain

First import the group policy module - import-module grouppolicy

Change the TargetType from user to group when setting permissions for groups. The target name is the samaccountname (both users and groups have this). Set-GPPermissions -all -TargetName username -TargetType user -PermissionLevel gpoeditdeletemodifysecurity

Exchange cmdlets to show inbound/outbound mail size restrictions

Show the maximum sending message size for Exchange 2007/2010 send connectors:
Get-sendConnector | format-list Identity,MaxMessageSize

Show the maximum receiving message size for receiving messages for Exchange 2007/2010 receive connectors:
Get-ReceiveConnector | format-list Identity,MaxMessageSize

Show the maximum receive as well as send message sizes:
Get-TransportConfig | format-list max*size

Run a PowerShell script using Task Scheduler

Find the uninstall string for software using PowerShell

In this example we search for uninstall strings for firefox:
Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object {$_.DisplayName -match "firefox"} | Select-Object -Property DisplayName, UninstallString

Removing computers from the domain

Remove-Computer -ComputerName hostname -UnjoinDomainCredential domain\username -verbose -Force -Restart

Show PowerShell command history

You can use Get-History to show your previous commands.

To run a previous command use Invoke-History x where x is the Id of the command from Get-History.

Change volume name

Use get-volume to view volume names and drive letters. To change the volume name type:
Set-Volume -DriveLetter D -NewFileSystemLabel Corporate_Data

Determine which SCCM antimalware policies are applied to your computer

You can view these via the registry:

Or via PowerShell:
$EmptyPolicy= @()
$EPPolicy = Get-wmiObject -namespace “Root\ccm\Policy\Machine\ActualConfig” -query “Select Name from CCM_AntiMalwarePolicyClientConfig” | ForEach-Object {$EmptyPolicy+=$_.Name}
$EmptyPolicy | Group-Object | Select-Object -Property Name –Unique

Mass move script

Get-Content C:\hostnames.txt |
Foreach-Object {
$source = '\\' + $_ + '\c$\ide\eclipse_64'
$source2 = '\\' + $_ + '\c$\ide\eclipseDropins'
$destination = '\\' + $_ + '\c$\ProgramData'
move-item -verbose -path $source -destination $destination
move-item -verbose -path $source2 -destination $destination

TRIM log removal script

$included =@('TRIMWorkgroup*.log', 'TRIMEvent*.log')
$excluded =@('*.exe*')
$target = get-childitem -path D:\HPTRIM\ServerLocalData\TRIM\Log -recurse -include $included -exclude $excluded | where { ((get-date)-$_.lastwritetime).days -ge 14}
$target | remove-item -recurse -force
get-date > c:\TRIM_Deletion_Log.txt
$target >> c:\TRIM_Deletion_Log.txt

View domain and forest function levels

Show domain functional level:
Get-ADDomain | Select-Object -Property domainmode

Show forest functional level:
Get-ADforest | Select-Object -Property forestmode

Create an encrypted password and store it in a file

The below commands create an encrypted password and store it in a password.bin file.
Add-Type -assembly System.Security
$passwordBytes = [System.Text.Encoding]::Unicode.GetBytes("enter_password")
$entropy = [byte[]](1,2,3,4,5)
$encrytpedData = [System.Security.Cryptography.ProtectedData]::Protect($passwordBytes, $entropy, 'CurrentUser')
$encrytpedData | Set-Content -enc byte c:\password.bin

The below commands read the encrypted file and assign the unencrypted password to the password variable.
$encrytpedData = Get-Content -enc byte c:\users\pbearen\password.bin
$entropy = [byte[]](1,2,3,4,5)
$unencrytpedData = [System.Security.Cryptography.ProtectedData]::Unprotect($encrytpedData, $entropy, 'CurrentUser')
$password = [System.Text.Encoding]::Unicode.GetString($unencrytpedData)

Using Where-Object to filter results

The two below commands are separate examples of using where-object to find a particular username:

get-aduser -filter * | Where-Object {$_.samaccountname -match "username"}

get-aduser -filter * | Where-Object {$_.samaccountname -like "*username*"

Using Where-Object

Where-Object can be used to filter results. In the below example I am using two different ways to filter the output to show only KB2718695 if it exists.:
Get-HotFix | Where-Object {$_.hotfixid -like '*2718695*'}
Get-HotFix | Where-Object -property hotfixid -like '*2718695*'

However, when you want to add a Boolean condition you need to use the placeholder method eg $_.property_name
Get-Service | Where-Object {$_.status -Match 'running' -and $_.displayname -like '*spool*'}

Using Where-Object to filter results on multiple boolean conditions

Note, the matches are case insensitive ie BHP will return instances of bhp.
get-aduser -Properties company | where-object {$_.company -match 'BHP' -or $_.company -match 'WOW' -or $_.company -match 'Coles'} | Select-Object -Property samaccountname, company | Sort-Object -Property company

Filtering results using -Filter

You can use -Filter instead of where-object to filter results. You actually need to use -filter when piping output into a cmdlet like set-adaccountexpiration (where-object doesn't work).
get-aduser -Filter {company -eq 'WOW' -or company -eq 'BHP' -or company -eq 'peoplebank'} | Set-ADAccountExpiration -DateTime "DD/MM/YYYY"

Determine OS

Get-WmiObject -class win32_operatingsystem | Select-Object -Property name

Add a DNS A record

The below command adds an A record for serverA with an IP address of in the nickbeare.com forward lookup zone:
Add-DnsServerResourceRecordA -Name serverA -ZoneName nickbeare.com -IPv4Address

Display and clear client DNS cache

Show all locally cached DNS entries:

Clear all locally cached DNS entries:

List all shares on a PC

Get-wmiobject -class win32_share -ComputerName hostname

Show the time on a remote PC

Get-wmiobject -class win32_operatingsystem -property localdatetime -ComputerName hostname

The ANR property

Anr is an AD object property that returns several values including distinguishedname, name, objectclass, objectguid. You can return it using PowerShell and cmd.exe:
Get-adobject –ldapfilter “(anr=username)”
Dsquery * -filter “(anr=username)”

List a remote computers IP address

get-wmiobject -class win32_networkadapterconfiguration -filter "ipenabled=$true" -ComputerName hostname

Adding firewall rules with PowerShell

There are a few ways to do this, just run get-command -noun *firewall* to view methods.

One way is via port and protocol:
New-NetFirewallRule -DisplayName "Block Outbound Port 80" -Direction Outbound –LocalPort 80 -Protocol TCP -Action Block

Another way is via display group name (this rules allow the firewall MMC):
Enable-NetFirewallRule -DisplayGroup ”Windows Firewall Remote Management”

Using Hashtables to rename properties

Hashtables can be constructed using select-object and format-table eg:
get-aduser -Identity admin_user | format-table -Property @{l='nickname';e={$_.name}}, @{l='Identifier';e={$_.sid}}

get-aduser -Identity admin_user | select-object -Property @{l='nickname';e={$_.name}}, @{l='Identifier';e={$_.sid}}

The where-object filterscript parameter

Get-ADUser -filter * | Where-Object -FilterScript {$_.name -eq 'pbearenadmin' -and $_.objectclass -eq 'user'}

Quest AD Module Commands

Show all DCs:
get-QADComputer -computerRole 'DomainController' | select-object -Property name, osversion, osname

Show all computer objects in an OU:
get-QADComputer -Searchroot "ou=computers,dc=csu,dc=edu,dc=au" | select-object name, osversion, operatingsystem

Show all groups a user is a member of:
Get-QADMemberOf -identity username

Show all users in an OU:
Get-QADUser -SearchRoot "ou=users,dc=csu,dc=edu,dc=au" | Select-Object -property samaccountname, email, accountisdisabled, homedirectory

Filtering with Where-Object:
Get-QADMemberOf -identity username | Where-Object -FilterScript {$_.name -eq 'domain users'}

Sorting results:
Get-QADMemberOf -identity username | Sort-Object -Property name -descending

Filtering and counting results from an OU:
Get-QADUser -SearchRoot "ou=users,dc=csu,dc=edu,dc=au" | select-object -property samaccountname, email, accountisdisabled | Where-Object -FilterScript {$_.accountisdisabled -ne 'True'} | Measure-Object

Count all DCs:
Get-QADGroupMember -Identity 'domain controllers' | Measure-Object

Find domain controllers according to name:
Get-QADGroupMember -Identity "domain controllers" | Sort-Object -Property name | where-object -FilterScript {$_.name -like 'DNO*'}

Show all object attributes and their values:
Get-QADUser JSmith -IncludeAllProperties -SerializeValues | Format-List

Show all object attributes, but not their values:
Get-QADUser -IncludeAllProperties -ReturnPropertyNamesOnly

Return a count of disabled accounts in the entire domain (note use -sizelimit x to return x number of results):
Get-QADUser -DontUseDefaultIncludedProperties -sizelimit 0 | Select-Object -Property accountisdisabled | Where-Object -FilterScript {$_.accountisdisabled -eq 'true'} | Measure-Object

Return a count of enabled accounts in the entire domain (note use -sizelimit x to return x number of results):
Get-QADUser -DontUseDefaultIncludedProperties -sizelimit 0 | Select-Object -Property accountisdisabled | Where-Object -FilterScript {$_.accountisdisabled -ne 'true'} | Measure-Object

Mass Ping Script

The below commands can be used to ping a subnet and record responses from hosts. In this example is pinged.

$ping = New-Object System.Net.Networkinformation.Ping
1..254 | % { $ping.send(“192.168.100.$_”) | select-object -property address, status }

Foreach loop that removes members from group

$members = get-content c:\temp\members.txt
foreach ($member in $members)

get-qadcomputer -identity $member | select-object -expandproperty DN | remove-qadgroupmember -identity 'CN=groupname,OU=groups,DC=corp,DC=bhp,DC=au' -whatif -verbose


Move computer objects to an OU

$members = get-content c:\temp\members.txt
foreach ($member in $members)
get-qadcomputer -identity $member | select-object -expandproperty DN | move-QADObject -NewParentContainer 'bhp.mil.au/old_pcs' -verbose

Find deleted objects using the Quest AD Module

The modification date/time reflects when the object was deleted:
Get-QADUser -Tombstone -Name username* | Select-Object -Property *

Creating bulk A, PTR, and CNAME records

$records = Import-Csv -path “c:\records.csv”
foreach ($record in $records)
dnscmd coredc1 /recordadd $record.Zone $record.NodeName $record.RRType $record.RRData

Input file records.csv

Create DNS A + PTR records in bulk using PowerShell

The below script can be used to create DNS A records and their associated PTR records. Sample input file format below:


$records = Import-Csv -path c:\new.csv
foreach ($record in $records)
Add-DNSServerResourceRecordA -computername DNS_Server_Name -name $record.nodename -zonename $record.zone -createptr -ipv4address $record.RRData -verbose

Removing DNS records in bulk using PowerShell

The below script can be used to remove DNS records of any type. Sample input file below:


$records = Import-Csv -path c:\old.csv
foreach ($record in $records)
Remove-DNSServerResourceRecord -computername DNS_Server_Name -name $record.nodename -zonename $record.zone -recorddata $record.RRData -RRType $record.RRType -confirm:$false -force -verbose

Creating bulk forward and reverse lookup zones

$zones = get-content “c:\zones.txt”
foreach ($zone in $zones)
dnscmd coredc1 /zoneadd $zone /DSPrimary

Input file zones.txt

The /zoneadd switch is smart enough to detect reverse lookup zones by name (*.in-addr.arp) and create them accordingly.
For a primary zone use /Primary. /DSPrimary is for AD Integrated.

View pwdlastset attribute with Quest AD Module

To view pwdlastset you need to make it an included property:
get-content c:\temp\expired_computers.txt | get-qadcomputer -includedproperties pwdlastset | select-object -property name, pwdlastset | export-csv -path c:\temp\comps_4.csv -notype

Extracting user object information using the Quest AD Module

input.txt holds one username per line.
get-content 'c:\input.txt' | get-qaduser -searchroot "ou=Accounts,DC=test,DC=local" | select-object -property firstname, lastname, accountexpires, accountexpirationstatus, name, accountisdisabled, dn | export-csv -path 'c:\output.csv' -notype

List object group membership using the Quest AD Module

Show the expanded group membership of an AD object (user, group, computer). Output is in CSV format with one object name and group name per line. The indirect parameter shows nested group membership. The input file is a text file with one object name per line.

function GetInfo($objects) {
foreach ($object in $objects)
$membership = get-qadmemberof -identity $object -indirect $memberShip | %{
$properties = @{
objectName = $object
memberOfName = $_.Name
$infoObject = new-object psobject -property $properties
$objects = get-content -path 'C:\temp\names.txt'
remove-item c:\temp\info.csv
GetInfo $objects | export-csv c:\temp\info.csv -noclobber -notypeinfo

List members of multiple groups using the Quest AD Module

Show the members of multiple groups. Output is in CSV format with one group name and user (member) per line. The indirect parameter shows users who are a member of the group via a nested group. The input file is a text file with one username per line.

function GetInfo($objects) {
foreach ($object in $objects)
$membership = get-qadgroupmember -identity $object -indirect $memberShip | %{
$properties = @{
objectName = $object
memberOfName = $_.Name
$infoObject = new-object psobject -property $properties
$objects = get-content -path 'C:\temp\names.txt'
remove-item c:\temp\info.csv
GetInfo $objects | export-csv c:\temp\info.csv -noclobber -notypeinfo

Bulk creating groups

Method 1. DN is the OU where you want to put the groups. Input file contains group name and description columns.

$DN = 'OU=TST,DC=BHP,DC=mil,DC=au'
$groups = Import-Csv -path “c:\temp\groups.csv”
foreach ($group in $groups)
dsadd group ("CN=$($group.name.trim()),$($DN)") -secgrp yes -scope g -desc $group.description

Method 2.

$groups = import-csv -path c:\temp\members.csv
foreach ($group in $groups)
New-ADGroup -Path "OU=AccountDeptOU,DC=AppNC" -Name $group.name -GroupScope DomainLocal -GroupCategory Security -Description $group.description

User Creation Script - Includes adding group membership based on a sample user

$DN = 'OU=BHP,DC=bhp,DC=corp,DC=au'
$upn = '@bhp.corp.au'
$users = Import-Csv -path "c:\temp\users.csv"
foreach ($user in $users)
$UserDN = ("CN=$($user.name.trim()),$($DN)")
$props = @('user', $UserDN, '-samid', $user.name, '-upn', "$($user.name)$($upn)", '-pwd', $user.password, '-mustchpwd', 'yes', '-desc', $user.description, '-display', $user.name )
dsadd @props
dsquery user -samid sample.user | dsget user -memberOf | dsmod group -addmbr $UserDN -c

Service Account Creation Script

$DN = 'OU=Accounts,DC=info,DC=net'
$upn = '@info.net'
$users = Import-Csv -path "c:\temp\service3.csv"
foreach ($user in $users)
$props = @('user', ("CN=$($user.name.trim()),$($DN)"), '-samid', $user.name, '-upn', "$($user.name)$($upn)", '-disabled', 'no', '-pwd', $user.password, '-mustchpwd', 'no', '-desc', $user.description, '-pwdneverexpires', 'yes', '-canchpwd', 'no', '-display', $user.displayname )
dsadd @props

Add DHCP reservations in bulk

$members = import-csv -path c:\temp\dhcp2.csv
foreach ($member in $members)
netsh dhcp Server $member.server Scope $member.scope Add reservedip $member.ip $member.mac $member.name $member.comment

Sample input file (csv):

List all groups in an OU

Get-ADGroup -SearchBase "OU=Groups,DC=bhp,DC=com" -filter * -Properties name | Select-Object -Property name | Export-Csv -Path C:\temp\groups.csv

Add a member to a list of groups

In this example the Domain Admin group is added to each group in groups_v2.txt.

$groups = get-content -path c:\temp\groups_v2.txt
foreach ($group in $groups)
Add-ADGroupMember -Identity $group -Members 'Domain Admins' -verbose

Bulk renaming groups using Quest

The below script takes a list of old and new group names and renames each group's names (samaccountname and object name).
$groups = import-csv -path c:\temp\groups.csv
foreach ($group in $groups)
rename-qadobject -identity $group.old -newname $group.new -verbose
get-qadgroup -identity $group.old | set-qadgroup -displayname $group.new -samaccountname $group.new -verbose

Create new active computer objects and place them in an OU

$OU = "OU=Desktops,DC=Domain,DC=Com"
$computers = Import-Csv -Path C:\computers.csv
foreach ($computer in $computers)
$DNSHostName = $computer.name+".DOMAIN.COM"
New-ADComputer -Name $computer.name -Path $OU -DNSHostName $DNSHostName -Enabled $true -Verbose

Search for a group policy by name

Get-GPO -all | Where-Object {$_.displayname -like "*example*"}

Export DHCP scope details

The below command queries dhcpserver and exports to CSV, details on any scopes containing the name "scope name".
Get-dhcpserverv4scope –computername dhcpserver | where-object {$_.name –like “*scope name*” | export-csv –path c:\temp\file.csv

Return the first 3 letters of a string and assign to a variable.

[PS] C:\>$computer
[PS] C:\>$computer.substring(0,3)
[PS] C:\>$pc = $computer.substring(0,3)
[PS] C:\>$pc

Removing a specific character from a string

To remove " from a string:
$quoteless_ou = $ou.trim('"')

You can also use trimstart() and trimend() to remove from the start or end of a string respectively.

Move computers to their respective OU

Script was used to move computers back to their correct OU. The correct OU being the first three letters of the computer's name.

$computers = get-content c:\temp\nicks_comps.txt
foreach ($computer in $computers)
$three = $computer.Trim().Substring(0,3)
$ou = dsquery ou -name $three
$quoteless_ou = $ou.trim('"')
get-qadcomputer -identity $computer | select-object -expandproperty DN | move-QADObject -NewParentContainer $quoteless_ou -verbose

Script used to reset training accounts

$users = get-content c:\AD_Reporting\users.txt
foreach ($user in $users)
set-qaduser -identity $user -userpassword 'insert_password' -UserMustChangePassword $true -description 'insert_description' -AccountExpires $null -verbose
unlock-QADUser -identity $user -verbose
enable-qaduser -identity $user -verbose
$homez = '\\server\share\' + $user + "\*" remove-item -force -recurse -path $homez -verbose

Script that uses an array to produce a user status report

$BHP_persons = dsquery group -name "group_name" /domain bhp.com | dsget group -members -expand -c | dsget user -samid -c
$date = get-date -format ddMMyyyy
$date2 = "BHP_" + $date
$headings = " Account_Name Expiration_Date Disabled"
echo $headings > C:\BHP_Reporting\$date2.csv
$myarray = @()
foreach ($person in $BHP_persons)
$priv_person = $person.trim() + "_admin"
$myarray += $priv_person | dsquery user -name $priv_person /domain domain.local | dsget user -samid -disabled -acctexpires -c
$myarray[1] | out-file C:\BHP_Reporting\$date2.csv -Append
$myarray= @()
Send-MailMessage -To insert_email_address -From insert_email_address -Subject "BHP Account Report" -SmtpServer insert_smtp_server -Attachments C:\BHP_Reporting\$date2.csv -Body "Insert Message Text Here."

Disable or enable a list of computer objects

$computers = get-content c:\scripts\disable_computers.txt
foreach ($computer in $computers)
dsquery computer -name $computer | dsmod computer -disabled yes
# -disabled no enables a computer.

Calling the quest module using a scheduled task

Create a batch file that calls the powershell script ie:
powershell -command "& 'C:\Scripts\script.ps1'"

In your powershell script you will need the below code at the top to call the quest module:
Add-PSSnapin Quest.ActiveRoles.ADManagement

Bulk computer object deletion script

$computers = get-content c:\scripts\comps.txt
foreach ($computer in $computers)
dsquery computer -name $computer | dsrm -noprompt

AD Module Computer Object Deletion Script

The below script can be used to scan for computer object names containing specific serial numbers in particular OUs. It then deletes them.

Import-module –name activedirectory
$serials = get-content –path serial_numbers.txt
Foreach ($serial in $serials)
$computer = “*serial*”
Get-adcomputer –filter {name –like $computer} – searchbase “OU=test,DC=domain,DC=com” –searchscope subtree | remove-adobject –verbose –recursive –confirm:$false
Get-adcomputer –filter {name –like $computer} – searchbase “OU=tes2,DC=domain,DC=com” –searchscope subtree | remove-adobject –verbose –recursive –confirm:$false
#repeat lines for other OUs

DC NTP Check Script

The below script run be use to check that the time across all DCs in a domain is consistant.

$array = "Running NTP Check...", ($date = (get-date | Out-String).trim())
$dcs = dsquery server -o rdn
foreach ($dc in $dcs)
$array += w32tm /monitor /computers:$dc | Where-Object {$_ -match 'NTP:' -or $_ -match $dc}
$array | out-file Monitor.txt

Link GPOs to particular OUs

The below script can be used to link multiple GPOs to given OUs (and enable the links). Just make sure that the GPOs in the input file match their displayname.

$gpos = Get-Content -Path gpos.txt
foreach ($gpo in $gpos)
new-gplink -name $gpo -target "OU=sample,DC=DOMAIN,DC=COM" -linkenabled yes
new-gplink -name $gpo -target "OU=sample2,DC=DOMAIN,DC=COM" -linkenabled yes

Append loop output to a CSV file without the -append switch

In export-csv the -append switch is not available in earlier version of powershell. However, you can still append foreach output into a CSV file using an array.

$target = @()
$peeps = import-csv -path names.csv
foreach ($peep in $peeps)
$target += get-qaduser -identity $peep.old_username -IncludedProperties profilepath, homedirectory | Select-Object -Property samaccountname, mail, userprincipalname, homedirectory, profilepath
$target | export-csv -path validated_names.csv -notypeinfo

Assigning permissions to all group policy objects using powershell

The below example grants authenticated users read access to all GPOs.

Get-GPO -All | select-object -property displayname | Set-GPPermissions -TargetName "Authenticated Users" -TargetType Group -PermissionLevel GpoRead -verbose -confirm:$false

Turning off the Windows Firewall with PowerShell

You can turn off domain, private and public firewalls:
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False

Allowing MMCs to access Server Core

By default, the firewall settings in Server Core block all MMCs such as services.msc, compmgmt.msc and Windows Explorer.

Enable-NetFirewallRule -DisplayGroup "Windows Firewall Remote Management"
Enable-NetFirewallRule -DisplayGroup "Remote Service Management"

Check if DCs have DHCP Scavenging enabled

$dcs = dsquery server -o rdn /domain bhp.com
foreach ($dc in $dcs)
$output = dnscmd $dc /info
$string = $output | select-string "scavenging"
write-host $dc
write-host $string
write-host ""

Another way to do csv output

$users = import-csv -path file.csv
foreach ($user in $users)
$user_check = get-qaduser -sizelimit 0 -identity $user.name -includedproperties accountisdisabled, homedirectory, profilepath, samaccountname, lastlogontimestamp | select-object -property HomeDirectory, profilepath, samaccountname, accountisdisabled, lastlogontimestamp
$output = $user.name + ',' + $user.lastwritetime + ',' + $user_check.samaccountname + ',' + $user_check.homedirectory + ',' + $user_check.profilepath + ',' + $user_check.accountisdisabled + ',' + $user_check.lastlogontimestamp
$output | out-file output.csv -append

Show Network Adapter Config

Useful for showing IP config info on a remote host such as DHCP server:
Get-wmiobject –class win32_networkadapterconfiguration –filter IPEnabled=TRUE –computername hostname | select-object –property *

Show all environment variables in powershell

Get-ChildItem env:
Find a particular one:
Get-ChildItem env:logonserver

Shutdown script to use when WinRM is disabled/blocked

Substitute -s for -r to do a reboot.

$computers = get-content c:\scripts\computers.txt
foreach ($computer in $computers)
shutdown.exe -m $computer -s -f -t 0

Scheduling jobs with PowerShell

Below is a simple job that runs once at 2am and starts up a VM.
$trigger = New-JobTrigger -once -at 2:00
Register-ScheduledJob -Name Turn_VM_On -Trigger $trigger -ScriptBlock {start-vm -name vm_name}

View NTFS permissions on a folder using PowerShell

Get-acl –path \\hostname\c$\share | select-object -expandproperty access | select-object –property identityreference, accesscontroltype, filesystemrights

See if a KB is installed on your Domain Controllers

The below commands scan all the DCs in your domain and check to see if KB3111561 is installed:

$dcs = Get-ADDomainController -Filter * | Select-Object -expandProperty name
foreach ($dc in $dcs) { Get-HotFix -computername $dc -Id KB3111561 }

Run a PowerShell script using a Scheduled Task

In the program/script section of the action user PowerShell to run you script, see below:
Powershell –file “c:\temp\something.ps1”

Finding which DHCP server a scope is hosted on

You can use the below script to scan all authorised DHCP servers in the domain and search for a DHCP scope. In the below example the search is conducted on the scope's name, but you could also use the subnet or scope ID ie (use .scopeid instead of .name).

$servers = get-dhcpserverInDC | select-object -expandproperty dnsname
foreach ($server in $servers)
Write-host $computer
Get-dhcpserverv4scope –computername $server | where-object {$_.name –like “*Sydney*”} | format-table –auto

Bulk DHCP Scope Creation Script

Sample input file below. The top row are headings, the second row is where you put the scope data:


PowerShell Script:
$scopes = import-csv -path c:\dhcp.csv
foreach ($scope in $scopes)
Add-DhcpServerv4Scope -Name $scope.name -StartRange $scope.startrange -EndRange $scope.endrange -SubnetMask $scope.subnetmask -Description $scope.description –cn $scope.cn -verbose -whatif

Uptimer - calculate the boot time of Windows hosts

List your Windows hostnames in comps.txt:
$comps = get-content -path c:\temp\comps.txt
foreach ($comp in $comps)
write-host $comp
systeminfo /s $comp | select-string "Time:"

How to verify TCP port connectivity on Windows without using Telnet

In PowerShell you can use the below. Replace x.x.x.x with the destination IP address, and 53 with the desired port number. If the command runs successfully then the port is open. You can verify this with $socket. If the port is closed the command will error out.

$socket = New-Object system.net.sockets.tcpclient ("x.x.x.x","53")

SCOM Maintenance Mode Script

The below scripts can be used to put multiple computers into maintenance mode in SCOM. All files reside in the same directory, in this case C:\script_location.
Create a text file with the hostnames (hostnames.txt) you would like to put into SCOM maintenance mode.

Run the below batch file to read the above input file. It will execute the below PowerShell script. You may want to change the duration in the batch file, it is in minutes ie the example below will put computers into maintenance mode for 30 minutes.
powershell -file c:\script_location\MaintMode.ps1 -FileName hostnames.txt -Duration 30

The below PowerShell script puts the hostnames in maintenance mode. You will need to sub in your values for path, domain and new-SCOMManagementGroupConnection computername.
# PS C:\script_location> .\MaintMode.ps1 -FileName hostnames.txt -Duration 10
# Functions
# Module
Import-Module OperationsManager
new-SCOMManagementGroupConnection -ComputerName insert_scom_server_name
# Script
$path = "C:\script_location"
$domain = "bhp.mil.au"
# Params
#Get Server list
$MyFile = Get-content "$path\$Filename"
foreach($srv in $MyFile)
Write-host "ServerName : $srv"
$startTime = [DateTime]::Now
$endTime = $startTime.AddMinutes($Duration)
$srv += ".$domain"
$Class = get-SCOMclass | where-object {$_.Name -eq "Microsoft.Windows.Computer"};
$Instance = Get-SCOMClassInstance -Class $Class | Where-Object {$_.Displayname -eq "$srv"};
Start-SCOMMaintenanceMode -Instance $Instance -Reason "PlannedOther" -EndTime $endTime -Comment "Scheduled Maintenance Window"