A Guide to PowerShell – part 3

Welcome to part 3 of 3 of The Solving A guide to PowerShell. Check also Part 1 and Part 2.

In this final part we will combine the concepts learnt so far and demonstrate practical uses of PowerShell for System Administrators. PowerShell can make the life of an IT Administrator much easier and can be used to manage your infrastructure effortlessly. PowerShell is a fantastic tool at making server management simple, it is great at gathering information about your Server and displaying that data in different formats.

This part of the guide will introduce several new concepts. Take your time and work through each part individually.

What software is installed on my system?

Type Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize

List Available programs

The command above will display the installed programs on your system. If you deconstruct the command you will see it does this in quite a complex way:

  • Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*  – This part of the command tells PowerShell to look in HKLM and browse to  \Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall and get all properties inside. HKLM is the PowerShell filesystem for the Registry!
  • The rest of the command simply grabs specific data (DisplayName, DisplayVersion, Publisher, InstallDate) and outputs it to a Table.

Additionally, you can browse the registry direct from the Shell by typing cd HKLM:\ you can then navigate the HKLM just as if you were using Command Prompt or Windows Explorer.

What Windows patches are installed on my system?

Finding information about hotfixs and KB articles was extremely complex in PowerShell. Microsoft has recently released the cmdlet Get-Hotfix. This is a great tool for interrogating your infrastructure to see what Windows Update patches are installed, or to see if a particular hotfix is installed.

I found this knowledge was extremely useful when the WannaCry Ransomware exploit was released in 2017. PowerShell allowed me to search nearly every single Windows Server I manage to see which server was patched, and which was still outstanding and vulnerable.

Once the script was written, it took minutes to produce a list of each vulnerable server (from several thousand servers)

Type Get-Hotfix | Format-table -autosize


This will produce a list of what KB are installed on your local system.

Now we can use the power of the shell to interrogate multple computers.  To do this we will introduce PowerShell ISE (integrated scripting environment).

Open PowerShell ISE and type the following into the script pane. Then press the green play button to run the script. You will need the text file of your servers that we created in Part 2 of the guide. As a reminder, here is the content I created earlier:

test file - hostnames

Now type into PowerShell ISE:

$servers =  get-content c:\temp\test.txt
foreach ($server in $servers)
{Get-HotFix -ComputerName $server | Select-Object PSComputername, HOTFIXiD, Installedon  | Sort-Object -Property InstalledOn -Descending}

Introducing ISE

This will output all the installed KB on my demo servers The-Solving-N1, The-Solving-N2 and The-Solving-N3:

If you want to search for a specific KB, for example KB2977629, you need to add the cmdlet Where-object HotfixID -eq “KB2977629” into the script.


$servers =  get-content c:\temp\test.txt
foreach ($server in $servers)
{Get-HotFix -ComputerName $server | Where-object HotfixID -eq “KB2977629” | Select-Object PSComputername, HOTFIXiD, Installedon  | Sort-Object -Property InstalledOn -Descending}

How do I search the Event Log for Errors?

The Event Log is a vital tool for looking at system issues. PowerShell can greatly improve the time and effort needed in seaching the event log.

type Get-Eventlog system -Newest 30 | Where-Object {$_.entryType -Match “Error”} | format-table -AutoSize

Query Sytem log

The above command will search the “SYSTEM” event log and display the newest errors in the last 30 alerts. You can change the Event log to search for the Application or Security Logs.

PowerShell and Active Directory

PowerShell can interact with every system toolset of Windows. It is very useful when interrogating Active Directory. Here are a selection of scripts I find useful when querying AD. Before we do anything we must have the Active Directory module enabled in the shell. The simpliest way to do this is to run these commands on your domain controller, however, this is not always possible so please note that you can also add this role directly onto your system (providing it is a member of the domain you wish to query).

Type Add-WindowsFeature RSAT-AD-PowerShell

Add-WindowsFeature RSAT-AD-PowerShell

Once installed you can now use the Shell to query and edit Active Directory. Please proceed with caution if working on a production environment.

Active Directory in PowerShell is another large subject to understand. Rather than go through every command step by step, here I have listed my favourite commands, the one’s that I use frequently when managing and maintaining Active Directory. You can use the get-help command to read in detail about these Active Directory cmdlets.

Querying Users

Querying user accounts is very simple in PowerShell. The commands in the table below will explain how to search for users, look for users with non-compliant password policies, users who are locked out, disabled accounts etc.

PowerShell Command What is does Category
Get-ADUser -Filter * -Properties * | where { $_.whenCreated -ge $week } | select Name,whenCreated | Sort Name Get Users created in the last Week, sorted by Name. USERS
Get-ADUser -Filter * -Properties PasswordNeverExpires | where { $_.PasswordNeverExpires -eq $true } | select Name | sort Name Get Users with passwords  set to “Never Expire”, sorted by Name USERS
Get-ADUser -Filter “Enabled -eq ‘$false'” | Select Name, UserPrincipalName | Sort name Get Users with INACTIVE accounts, Display Name and FQN, Sort by Name USERS
Search-ADAccount -AccountDisabled -UsersOnly | FT Name,ObjectClass -A Get Users with DISABLED accounts, Display Name and FQN, Sort by Name USERS
Search-ADAccount -LockedOut | Format-Table name,lastlogondate, lockedout, objectclass, passwordexpired, passwordneverexpires Find Users with locked Accounts USERS
Search-ADAccount -AccountInactive -TimeSpan 90.00:00:00 -UsersOnly |Sort-Object | FT Name,ObjectClass -A Find User Accounts not used for last 90 days USERS
Get-ADuser -Filter {name -like “*”} -properties *|select @{N=”Account”;E={$_.name}},@{N=”Name”;E={$_.givenname}},@{N=”LastName”;E={$_.surname}},@{N=”Mail”;E={$_.mail}},@{N=”AccountEnabled”;E={$_.enabled}},@{N=”MemberOf”;E={(Get-ADPrincipalGroupMembership $_).name -join (“`r`n”,”,,,,,”)}} | Sort-Object “Account” | FT -AutoSize Get all users group membership. Sorts data and formats as a table. Use Export-CSV to output to CSV file. USERS
Get-ADUser -Filter * -Properties LastLogonDate | ? { $_.LastLogonDate -eq $null } | Select name,samaccountname


Find users who have Never Logged on USERS



Querying Groups

Group membership in Active directory will tell you which users are members of which group. This can be extremely useful when you need to see who all the Domain Admins are, or ensure the security and compliance of your domain.

Command What it does Category
get-adgroup -filter * -Properties GroupCategory | Select name, groupcategory | FT -A List all your Groups in active directory GROUPS
Get-ADGroupMember -identity “Administrators” -recursive | select name List all members of the Administrators Group (Edit Group name accordingly) GROUPS
Get-ADPrincipalGroupMembership -identity Turbogeek | Sort-object | FT -property name, samaccountname -AutoSize Find which groups a user is a member of. (Edit username accordingly) GROUPS
Get-ADGroupMember -Identity Domain Admins” -Recursive | %{Get-ADUser -Identity $_.distinguishedName -Properties Enabled | ?{$_.Enabled -eq $false}} | Select DistinguishedName,Enabled Find Disabled Users in the Domain admins group (Edit Group name accordingly) GROUPS


Querying Active Directory Infrastructure

These commands will give you environmental information about your estate.

Command What it does Category
Get-ADDomainController -Filter * | Format-table name,domain, forest,site, ipv4address, operatingsystem Find the Domain controllers on your estate DC
Get-ADDomainController -Filter {IsGlobalCatalog -eq $true} | Select-Object Name,ipv4address,isglobalcatalog, operatingsystem | FT -A Find Global Catalog Servers in Domain, useful if you have more than one domain controller. DC
Get-ADDomainController -Filter {IsReadOnly -eq $true} Find Readonly domain controllers if applicable to your infrastructure. (Branch Servers) DC
Get-ADComputer -Filter ‘Name -like “The-Solving-N1*”‘ -Properties canonicalName, CN, created, IPv4Address, objectclass, OperatingSystem, OperatingSystemServicePack | FT -A Find Domain computers like “The-Solving-N1”, displays useful info in table DC
Get-ADForest | Select-Object -ExpandProperty ForestMode Get AD Forest level DC
Get-ADDomain | Select-Object -ExpandProperty domainmode Get AD Domain level DC
Get-ADReplicationConnection -Filter {AutoGenerated -eq $true} Get replication details on domain. This will only return data is you have more than one domain controller. DC
$datecutoff = (Get-Date)
Get-ADComputer -Filter {LastLogonTimestamp -lt $datecutoff} -Properties Name,LastLogonTimeStamp|  Select Name,@{N=’LastLogonTimeStamp’; E={[DateTime]::FromFileTime($_.LastLogonTimeStamp)}}
Run this script from PowerShell ISE. Set the $datecutoff and this will tell you last time a computer logged in DC


Editing Active Directory

You can also use PowerShell to edit Active Directory. Use this with caution especially if you are learning PowerShell.

Command What it does Category
Disable-ADaccount -identity The-Solving Disable account The-Solving USERS
Enable-ADaccount -identity The-Solving Enable account The-Solving USERS
Set-ADAccountExpiriation -Identity The-Solving -datetime “07/01/2019” Set Account The-Solving to expire on 7th Jan 2019 USERS
Clear-ADAccountExpiration -identity The-Solving Clear account expiry date USERS
Set-ADAccountPassword -identity The-Solving -reset -newpassword (Convertto-Securestring -asplaintext “Passw0rd123!” -Force) This will change users password securely and encyrpt password transmissions – essential USERS
Unlock-ADAccount -identity The-Solving Unlocks The-Solving Account USERS
New-AdGroup -Name “Test Users” -SamAccountName TestUser -GroupCategory Security -GroupScope Global -displayname ‘Test Users’ -Path “OU=Groups, OU=Resources, DC=TEST, DC=UK -Description “All Test Users” This will create a Security Group called Test Users in the OU Groups > Resources

(Edit as approrpriate)

Set-ADGroup -Identity ‘Test Users’ -groupcategory Distribution -groupscope Universal -Managedby ‘TurboGeek’ This will edit the Group Test Users and make it a Universal, distribution group managed by me. (Edit as appropriate) GROUPS
search-adaccount -lockedout | unlock-adaccount -passthru -confirm This command will search active directory and unlock all locked user accounts in AD. This is a crude but effective was of doing bulk unlock of accounts USERS

That completes The Solving A Guide to PowerShell, this has been a whistlestop tour and introduction to PowerShell. I hope that it has given you a taste of what PowerShell can do. We have literally just scratched the surface with what you can do in PowerShell. I have been learning PowerShell for 3 years and every single day I use it I am learning new techniques, tips and tricks. It is a wonderful tool for system administrators, and it can make the system administrators task much easier.

Read related articles