PowerShell scripts: examples to review and adapt
These pages contain individual scripts to read and adapt in PowerShell. Check the prerequisites, target scope and expected output before running one. Use the Script library to find a reporting workflow or Practice to rehearse a smaller pipeline.
Choose your next task: short checked exercises · type and inspect a pipeline · assemble command blocks · a short daily task · a complete weekly report · choose a reporting workflow ·
Find 35 scripts
Hunt down misconfigurations, stale objects, and security risks.
Find accounts in an unexpected OU
Every user object is retrieved, then Where-Object keeps the ones whose DistinguishedName fails to match a regular expression describing the approved containers.
Find Azure resources missing required tags
Inspect Azure resource tags with Get-AzResource and identify resources missing required keys before planning any changes.
Find changed PowerShell files in Git
git diff with --name-only prints paths instead of patch content, and the pathspec arguments after the double dash restrict output to ps1 and psm1 files.
Find Defender exclusions
Inventory Microsoft Defender exclusions and review paths, processes, and extensions for unexpected entries. Check each exception against the approved baseline.
Find disabled Entra users
The -Filter argument hands accountEnabled eq false to Graph as an OData expression so the service performs the selection.
Find disconnected adapters
Use Get-NetAdapter to list interfaces whose status is not Up. Include the interface name, status, and driver description for investigation.
Find duplicate mail addresses
Find user accounts sharing the same mail address. The script excludes empty values, groups addresses, and returns only duplicates.
Find duplicate SPNs
Query Active Directory servicePrincipalName values, expand the collections, and group repeated SPNs to investigate duplicate registrations.
Find empty directories
Find empty folders with Get-ChildItem and Where-Object. Count hidden and system entries when deciding whether a directory is empty.
Find empty security groups
Get-ADGroup returns security groups, then ForEach-Object tests each by calling Get-ADGroupMember against it. Explore syntax and examples on this page.
Find enabled users without email
Enabled users are retrieved with the mail attribute requested explicitly, and the intent of the middle stage is to keep only accounts where mail holds nothing.
Find established endpoints
Group established TCP connections by remote address, then sort by count to find the endpoints with the most concurrent connections.
Find expiring machine certificates
Find local-machine certificates with an expiry before a 30-day cutoff. Report subject, thumbprint, expiry, and private-key availability.
Find external forwarding rules
Find mailbox forwarding rules that send mail outside the organization and review the destination and rule details. Flag unapproved destinations.
Find failed scheduled tasks
Get-ScheduledTask enumerates every registered task, and piping it into Get-ScheduledTaskInfo attaches the runtime history to each.
Find guest users
A userType eq 'Guest' filter is evaluated by Graph, with the literal in single quotes because OData string comparisons require them.
Rank processes by total CPU time
Get-Process emits one process object per running executable, Sort-Object orders them by the CPU property in descending order, and -First 15 trims the tail.
Find high memory processes
The pipeline sorts Get-Process output on WorkingSet64, the resident set in bytes as reported by the 64-bit counter, then keeps the top fifteen.
Find Hyper-V checkpoints
Get-VM feeds each guest into Get-VMSnapshot, which returns the checkpoints belonging to that machine. Review the script and sample output before adapting it.
Find inactive enabled users
Find enabled accounts with old sign-in activity, then review the date source and exclusions before acting on the report.
Find listening TCP ports
Get-NetTCPConnection with -State Listen returns only sockets sitting in the listening state rather than the full connection table.
Find locked-out users
Search-ADAccount -LockedOut asks the directory for accounts currently in a locked state, so the selection happens server-side with no client filtering involved.
Find low disk space on a server
Query fixed local disks with Get-CimInstance and Win32_LogicalDisk, calculate free space, and identify volumes below the script's threshold.
Find mailbox forwarding
Get-EXOMailbox runs with -PropertySets All so the forwarding attributes come back, since they sit outside the minimal default set this cmdlet returns.
Find old temporary files
Find old files in the current user’s temporary folder. Review the age filter and preview matches before deleting anything.
Find old VMware snapshots
Find VMware snapshots older than seven days with Get-Snapshot. Report the VM, snapshot name, creation date, and size in GB.
Find processes outside Windows directories
Query Win32_Process with Get-CimInstance to inspect executable paths outside C:\Windows, alongside process names and IDs.
Find stale computers
Find enabled AD computer accounts with a recorded LastLogonDate older than 120 days. Review the evidence before treating an account as unused.
Find stopped automatic services
Use Get-Service and Where-Object to find automatic-start services that are not running. Return service names and display names for investigation.
Find stopped Azure VMs
Filter Azure VM status data for stopped and deallocated machines. Keep the resource group and power state so the two conditions remain distinct.
Find unattached Azure disks
Get-AzDisk enumerates the managed disks in the subscription and Where-Object keeps those whose DiskState reads Unattached.
Find USB storage devices
Query Win32_DiskDrive for USB storage devices. Report model, device ID, size in bytes, and available serial numbers with PowerShell.
Find users whose passwords never expire
Get-ADUser filters server-side on PasswordNeverExpires being true and requests the same attribute so the value returns with each object.
Find users without a department
Find directory users without a department value and review account details before updating records. Report missing values without changing accounts.
Find users without a manager
The query pulls enabled users with the Manager attribute requested, filters down to accounts where that attribute is unpopulated, and reports the account name.
Inventory 20 scripts
Collect complete inventories of systems, services, and cloud resources.
Connector inventory
Inventory Exchange Online inbound and outbound connectors, including enabled state, connector type, and outbound recipient domains.
Distribution group inventory
Inventory distribution and mail-enabled security groups with Get-DistributionGroup, then report names and primary SMTP addresses.
Export OU inventory
Export Active Directory OUs to CSV with their names, distinguished names, and accidental-deletion protection settings. Explore syntax and examples on this page.
Inventory Azure resource groups
Inventory Azure resource groups and report names, locations, and tags for review. Inspect the example and verify the result.
Inventory Azure subscriptions
Get-AzSubscription lists the subscriptions the signed-in identity can see in the current tenant, and the projection keeps name, ID, tenant ID and State.
Inventory Azure VMs
Get-AzVM with -Status queries each machine's instance view in addition to its model, and that is what populates the PowerState property.
Inventory Entra groups
Inventory Entra ID groups with Microsoft Graph PowerShell, selecting the group properties needed for a directory report.
Inventory Entra users
Inventory all Entra users with Get-MgUser -All and request only the properties needed for the report. Include account fields needed for a directory review.
Inventory GPOs
Get-GPO -All enumerates every policy object in the domain and the projection keeps the display name with its GUID and both timestamps.
Inventory Hyper-V VMs
List Hyper-V guests with Get-VM and report state, CPU usage, assigned memory in bytes, and status for each virtual machine.
Inventory installed software
Get-ItemProperty reads the uninstall hives directly, covering both the native path and Wow6432Node so 32-bit packages on a 64-bit host are included.
Inventory network adapters
Inventory network interfaces with Get-NetAdapter. Report status, link speed, MAC address, and driver description beside each interface name.
Inventory service principals
List tenant service principals with Microsoft Graph PowerShell. Review application identities and the properties returned by the inventory.
Inventory VMware VMs
Inventory VMware virtual machines and report their identifying and operational properties with PowerCLI. Include power state and host details.
Inventory Windows build information
One Get-CimInstance call against Win32_OperatingSystem returns a single instance per machine. Review the script and sample output before adapting it.
Mailbox inventory
Get-EXOMailbox with -ResultSize Unlimited pages through all recipients rather than stopping at the default first thousand.
Shared mailbox inventory
Inventory shared mailboxes and report identifying properties for an Exchange Online review. Inspect the example and verify the result.
SharePoint site inventory
Inventory SharePoint Online site collections with Get-SPOSite -Limit All and inspect the returned site properties.
Teams inventory
Use Get-Team to report team names, Microsoft 365 group IDs, visibility, and archived status in a PowerShell inventory. Explore syntax and examples on this page.
Transport rule inventory
Get-TransportRule returns every rule in the organization and the projection keeps the name with State, Mode, Priority, and Description.
Audit & investigate 9 scripts
Security and compliance audits with actionable findings.
Audit firewall profiles
Get-NetFirewallProfile returns one object per profile, and Select-Object reports the profile name with Enabled plus the two default action fields.
Audit Hyper-V replication
Audit Hyper-V replication status and health across virtual machines, then inspect failures before remediation. Check the last sync.
Audit inbound firewall block rules
Get-NetFirewallRule is constrained by three parameters at once, returning rules that are enabled, inbound, and set to block.
Audit offboarding state
A single Get-ADUser call requests Enabled, MemberOf and LastLogonDate for the account named in $Sam. Review the script and sample output before adapting it.
Audit PowerShell script block logging
Read the PowerShell ScriptBlockLogging policy registry key with Get-ItemProperty and interpret missing settings before drawing conclusions.
Audit privileged groups
Audit membership of privileged groups and capture the principals that need review. Inspect the example and verify the result.
Audit users with risky delegation flags
Get-ADUser requests the delegation-related properties explicitly because they are not returned by default. Explore syntax and examples on this page.
Distribution group membership audit
The outer enumeration returns every distribution group, and for each one Get-DistributionGroupMember lists its members with its own unlimited result size.
Investigate account lockouts
Query Security event ID 4740 from the last eight hours. Inspect the timestamp, logging computer, and message for account-lockout evidence.
Report 11 scripts
Build readable reports for people, permissions, and systems.
Generate a GPO report
Create an HTML report of domain Group Policy settings with Get-GPOReport -All, including configured settings rather than only GPO names.
Generate a server health object
Combine server health measurements into a structured PowerShell object that can be inspected, filtered or exported.
Generate uptime report
Query Win32_OperatingSystem on each computer and calculate uptime from LastBootUpTime. Check unreachable hosts before using the report.
Mailbox permissions report
Inspect a mailbox’s access rights and inherited permissions with Get-EXOMailboxPermission before preparing a permissions report.
Mailbox size report
Use Get-EXOMailboxStatistics to report mailbox item counts and total sizes, then sort the results to inspect the largest mailboxes first.
Report Azure role assignments
Report Azure role assignments with Get-AzRoleAssignment, including principal identity, role, scope, and object type in the active context.
Report direct license counts
Get-MgUser -All requests AssignedLicenses alongside the display name.
Report domain controllers
List AD domain controllers with their sites, IPv4 addresses, operating systems, and global-catalog status using Get-ADDomainController.
Report FSMO role holders
Find all five FSMO role holders with Get-ADForest and Get-ADDomain. Read the forest-wide and domain-specific role properties separately.
Report local Administrators members
Get-LocalGroupMember resolves the group membership and returns each principal with two useful qualifiers. Explore syntax and examples on this page.
Report scheduled tasks running under stale accounts
The task inventory is read first, then each configured principal is translated to a SID. Review the script and sample output before adapting it.
Export 3 scripts
Export configuration and directory data for review.
Export DNS client configuration
List configured IPv4 DNS servers with Get-DnsClientServerAddress. Pair each interface with its resolver addresses and exclude empty lists.
Export IPv4 configuration
Get-NetIPAddress limited to -AddressFamily IPv4 returns every address bound to every interface. Review the script and sample output before adapting it.
Export recent Entra sign-ins
Review a PowerShell example for exporting recent Microsoft Entra sign-ins. Check access requirements and adapt the query to your reporting task.
Check, compare & verify 12 scripts
Validate state, compare copies, and test connectivity.
Check AD replication failures
Get-ADReplicationPartnerMetadata with -Target * and -Scope Domain collects the metadata each controller keeps about its replication partners.
Check certificate files in a folder
Get-ChildItem recurses through $Path with a -Filter of *.cer and reports each match with its full path, last write time, and size.
Check pending reboot indicator
Inspect a Windows pending reboot indicator with PowerShell. Review the specific check and its limits before using it in a wider maintenance workflow.
Check Windows Defender status
Get-MpComputerStatus returns the live state of the Defender engine as a single object. Review the script and sample output before adapting it.
Compare a copied file with SHA256
Get-FileHash reads each file using SHA256. LiteralPath treats brackets in filenames literally. Review the script and sample output before adapting it.
Compare DNS answers across servers
The loop asks each server in $DnsServers to resolve $Name and stamps the responding server onto every record with a calculated property.
Compare two directory inventories
Compare two directory inventories by path and file length to find additions, removals, and changes. Review differences before copying or removing any file.
Measure endpoint latency
Measure endpoint request latency and report response time and status for each target. Inspect the example and verify the result.
Test a TCP port across servers
The loop walks $Computers and calls Test-NetConnection against each with the port held in $Port, capturing the result object.
Trace DNS resolution across configured resolvers
The script asks each configured IPv4 DNS server directly. That removes the local resolver cache and server-selection ambiguity from the comparison.
Validate a module manifest
Get-ChildItem finds every psd1 file under the current directory and ForEach-Object runs Test-ModuleManifest against each full path.
Verify backup files arrived
Check a backup folder for files written since an expected timestamp. Report the twenty newest matching names, sizes, and write times.
Collect & summarize 5 scripts
Gather system facts and roll them into summaries.
Collect hardware summary
Collect CPU model, RAM in GiB, and BIOS version with Get-CimInstance, then combine the results into one PowerShell object.
Collect hotfix history
Get-HotFix wraps the Win32_QuickFixEngineering class and returns one row per servicing update. Review the script and sample output before adapting it.
Collect recent system errors
Query recent System errors with a server-side Get-WinEvent filter. Inspect the event time, ID and provider to focus the investigation.
Summarize computers by OS
Query AD computer operating systems, group matching values, and sort by count to report how many machine accounts use each OS.
Summarize failed logons
Summarize failed logons from Security event 4625 over a defined time range and inspect the account and source details. Group by account.
Scripting techniques 15 scripts
Reusable patterns: custom objects, logging, error handling, and testing.
Bulk add users to a group from CSV
Import-Csv reads the file into objects with one property per column, and ForEach-Object calls Add-ADGroupMember once per row.
Capture a terminating error
Get-Item runs with -EA Stop, which promotes its non-terminating error into a terminating one so control transfers into the catch block.
Create a calculated property
Select-Object accepts a hashtable with an n key naming the new column and an e key holding a script block that computes its value.
Create a custom reporting object
The [pscustomobject] cast applied to a hashtable literal produces one object whose properties are the hashtable keys, in the order they were written.
Explain pipeline members
Get-Process emits its objects and Get-Member consumes them, reporting the type name once and then every property, method, and property set that type exposes.
Inspect PowerShell command lines
A WQL filter restricts Win32_Process to the two PowerShell image names so the selection happens inside the CIM provider rather than in the pipeline.
Map active TCP connections to processes
Map active TCP connections to owning processes and review endpoints, states, and process names. Use process IDs to identify the owning application.
Retry a transient remote operation
Retry Invoke-Command up to three times with increasing delays. Use terminating error handling and rethrow the final failure.
Review default routes
Filtering Get-NetRoute to the destination prefix 0.0.0.0/0 returns only the default routes. Review the script and sample output before adapting it.
Review unsigned PowerShell scripts in a repository
Check PowerShell script signatures without executing the files. Identify unsigned scripts and review their signature status.
Run Pester tests and capture results
Run Pester tests from a test directory and capture structured results for a repeatable report. Inspect the example and verify the result.
Run PSScriptAnalyzer over a repo
Scan scripts and modules recursively with Invoke-ScriptAnalyzer, then export rule names, severity, and line numbers to CSV for review.
Use splatting for a CIM query
A hashtable holds parameter names as keys with their values attached, then @params in place of the individual parameters hands the whole set to Get-CimInstance.
Write a correlation-aware JSON operation log
Each line is a complete JSON object with an ISO-8601 UTC timestamp and one correlation ID. Review the script and sample output before adapting it.
Write structured audit records
A [pscustomobject] literal captures the timestamp and host name along with the action, status, and message supplied by the caller.
Error decoder
Paste the red text. The decoder names the kind of error it is and points at the lesson that fixes it. It never runs your code, and decoding happens entirely in your browser — your pasted error is never sent anywhere.