PowerShell Genie

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.

Script Windows PowerShell 5.1 and PowerShell 7

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.

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.

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.

Genie guideChoose a script

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.