Try Live
Add Docs
Rankings
Pricing
Docs
Install
Theme
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
PowerShell
https://github.com/microsoftdocs/powershell-docs
Admin
PowerShell is a cross-platform task automation and configuration management framework, consisting of
...
Tokens:
779,408
Snippets:
2,867
Trust Score:
8.9
Update:
1 month ago
Context
Skills
Chat
Benchmark
39.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# PowerShell Documentation PowerShell is a cross-platform task automation solution from Microsoft, consisting of a command-line shell, a scripting language, and a configuration management framework. Unlike traditional shells that work with text, PowerShell operates on .NET objects, enabling powerful data manipulation and seamless integration with the .NET ecosystem. It runs on Windows, Linux, and macOS, making it ideal for cloud management, CI/CD pipelines, and enterprise system administration. The PowerShell documentation repository provides comprehensive reference materials for PowerShell 7.x (the current cross-platform version) and Windows PowerShell 5.1. It covers cmdlet references, conceptual articles about scripting, remoting, modules, and best practices for automation. The documentation serves system administrators, DevOps engineers, and developers who need to automate tasks, manage cloud resources, or build deployment pipelines. ## Get-Command - Discover Available Commands The `Get-Command` cmdlet retrieves all commands installed on your system, including cmdlets, functions, aliases, and scripts. You can filter results by name, verb, noun, or parameter type to quickly find the command you need. ```powershell # Find all commands with names matching a pattern Get-Command -Name *-Process # Output: # CommandType Name Version Source # ----------- ---- ------- ------ # Cmdlet Debug-Process 7.0.0.0 Microsoft.PowerShell.Management # Cmdlet Get-Process 7.0.0.0 Microsoft.PowerShell.Management # Cmdlet Start-Process 7.0.0.0 Microsoft.PowerShell.Management # Cmdlet Stop-Process 7.0.0.0 Microsoft.PowerShell.Management # Cmdlet Wait-Process 7.0.0.0 Microsoft.PowerShell.Management # Filter by verb and noun Get-Command -Verb Get -Noun U* # Output: # CommandType Name Version Source # ----------- ---- ------- ------ # Cmdlet Get-UICulture 7.0.0.0 Microsoft.PowerShell.Utility # Cmdlet Get-Unique 7.0.0.0 Microsoft.PowerShell.Utility # Cmdlet Get-Uptime 7.0.0.0 Microsoft.PowerShell.Utility # Find commands that accept a specific parameter type Get-Command -ParameterType Process ``` ## Get-Help - Access Built-in Documentation The `Get-Help` cmdlet displays detailed documentation for any PowerShell command, including syntax, parameters, examples, and related links. Use the `-Online` parameter to open the latest web documentation. ```powershell # Get basic help for a cmdlet Get-Help Get-Process # Get detailed help with examples Get-Help Get-Process -Detailed # Get full help including all parameters Get-Help Get-Process -Full # Show only examples Get-Help Get-Process -Examples # Open online documentation in browser Get-Help Get-Process -Online # Update help files from Microsoft Update-Help -Module Microsoft.PowerShell.Management -Force ``` ## Get-Member - Inspect Object Properties and Methods The `Get-Member` cmdlet displays the properties and methods available on any object. This is essential for discovering what data you can access and what operations you can perform on command output. ```powershell # Discover properties and methods of process objects Get-Process | Get-Member # Output (partial): # TypeName: System.Diagnostics.Process # Name MemberType Definition # ---- ---------- ---------- # Handles AliasProperty Handles = Handlecount # Name AliasProperty Name = ProcessName # Kill Method void Kill() # Start Method bool Start() # Id Property int Id {get;} # ProcessName Property string ProcessName {get;} # CPU ScriptProperty System.Object CPU {get=$this.TotalProcessorTime.TotalSeconds;} # Show only methods Get-Process | Get-Member -MemberType Method # Show only properties Get-Process | Get-Member -MemberType Property # Get specific member details Get-Process | Get-Member -Name CPU ``` ## Get-Process - Manage System Processes The `Get-Process` cmdlet retrieves information about running processes on local or remote computers. You can filter by process name, ID, or other properties and use the output for monitoring or management tasks. ```powershell # Get all running processes Get-Process # Get specific process by name (supports wildcards) Get-Process -Name powershell* # Get process by ID Get-Process -Id 1234 # Get processes on remote computers Get-Process -Name powershell -ComputerName Server01, Server02 # Format output with specific properties Get-Process -Name powershell | Format-Table -Property Id, ProcessName, CPU, WorkingSet -AutoSize # Find processes using more than 100MB of memory Get-Process | Where-Object { $_.WorkingSet -gt 100MB } | Sort-Object WorkingSet -Descending | Select-Object -First 10 ProcessName, @{N='Memory(MB)';E={[math]::Round($_.WorkingSet/1MB,2)}} # Stop all non-responding processes Get-Process | Where-Object { $_.Responding -eq $false } | Stop-Process ``` ## Get-ChildItem - List Files and Directories The `Get-ChildItem` cmdlet retrieves items in a specified location, similar to `dir` in cmd.exe or `ls` in Unix shells. It works with the file system, registry, certificate store, and other PowerShell providers. ```powershell # List all items in current directory Get-ChildItem # List items including hidden files Get-ChildItem -Force # List items recursively Get-ChildItem -Recurse # Filter by file extension Get-ChildItem -Path C:\Scripts -Filter *.ps1 -Recurse # Find files modified in the last 7 days Get-ChildItem -Path C:\Logs -Recurse | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } # Find large files (over 100MB) Get-ChildItem -Path C:\ -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Length -gt 100MB } | Sort-Object Length -Descending | Select-Object FullName, @{N='Size(MB)';E={[math]::Round($_.Length/1MB,2)}} # Get directory sizes Get-ChildItem -Directory | ForEach-Object { $size = (Get-ChildItem $_.FullName -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum [PSCustomObject]@{ Name = $_.Name SizeMB = [math]::Round($size/1MB, 2) } } ``` ## Copy-Item, Move-Item, Remove-Item - File Operations These cmdlets provide complete file and folder manipulation capabilities including copying, moving, renaming, and deleting items with support for recursive operations and filtering. ```powershell # Copy a single file Copy-Item -Path C:\source\file.txt -Destination C:\dest\file.txt # Copy with overwrite Copy-Item -Path C:\source\file.txt -Destination C:\dest\file.txt -Force # Copy entire directory recursively Copy-Item -Path C:\source\folder -Destination C:\dest\folder -Recurse # Copy specific file types Copy-Item -Path C:\source\*.log -Destination C:\dest\ -Filter *.log # Move files Move-Item -Path C:\temp\*.txt -Destination C:\archive\ # Rename a file (using Move-Item) Move-Item -Path C:\file.txt -Destination C:\renamed-file.txt # Delete a file Remove-Item -Path C:\temp\file.txt # Delete directory and contents Remove-Item -Path C:\temp\folder -Recurse -Force # Delete files older than 30 days Get-ChildItem -Path C:\Logs -Recurse -File | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } | Remove-Item -Force ``` ## New-Item - Create Files and Directories The `New-Item` cmdlet creates new items such as files, directories, registry keys, and other provider-specific items. ```powershell # Create a new directory New-Item -Path C:\temp\NewFolder -ItemType Directory # Create a new empty file New-Item -Path C:\temp\newfile.txt -ItemType File # Create file with content New-Item -Path C:\temp\config.txt -ItemType File -Value "Setting1=Value1" # Create nested directories (parent directories created automatically) New-Item -Path C:\temp\level1\level2\level3 -ItemType Directory -Force # Create multiple files using a loop 1..5 | ForEach-Object { New-Item -Path "C:\temp\file$_.txt" -ItemType File -Value "Content for file $_" } ``` ## Get-Content, Set-Content - Read and Write Files These cmdlets read from and write to files. `Get-Content` returns each line as a separate object, enabling powerful text processing in the pipeline. ```powershell # Read entire file Get-Content -Path C:\data\log.txt # Read first 10 lines Get-Content -Path C:\data\log.txt -Head 10 # Read last 5 lines Get-Content -Path C:\data\log.txt -Tail 5 # Read file as single string Get-Content -Path C:\data\log.txt -Raw # Monitor file in real-time (like tail -f) Get-Content -Path C:\data\log.txt -Wait -Tail 10 # Write content to file (overwrites existing) Set-Content -Path C:\output\result.txt -Value "New content" # Append content to file Add-Content -Path C:\output\log.txt -Value "$(Get-Date): New log entry" # Process file line by line Get-Content -Path C:\data\servers.txt | ForEach-Object { Test-Connection -ComputerName $_ -Count 1 -Quiet } # Read and filter log file Get-Content -Path C:\logs\app.log | Where-Object { $_ -match 'ERROR' } | Select-Object -Last 20 ``` ## Select-Object - Choose Properties and Limit Results The `Select-Object` cmdlet selects specific properties from objects or limits the number of objects returned. It's essential for shaping output and creating custom objects. ```powershell # Select specific properties Get-Process | Select-Object -Property Name, Id, CPU # Select first 5 items Get-Process | Select-Object -First 5 # Select last 3 items Get-Process | Select-Object -Last 3 # Skip first 10 items Get-Process | Select-Object -Skip 10 # Select unique values Get-Process | Select-Object -Property Name -Unique # Create calculated properties Get-Process | Select-Object Name, Id, @{Name='MemoryMB'; Expression={[math]::Round($_.WorkingSet/1MB,2)}}, @{Name='CPUSeconds'; Expression={[math]::Round($_.CPU,2)}} # Expand array properties Get-Process | Select-Object -ExpandProperty Modules -ErrorAction SilentlyContinue # Select all properties except specific ones Get-Process | Select-Object -Property * -ExcludeProperty *64 ``` ## Where-Object - Filter Pipeline Objects The `Where-Object` cmdlet filters objects in the pipeline based on property values or script blocks. It's the primary way to select specific items from command output. ```powershell # Filter by property value Get-Process | Where-Object { $_.CPU -gt 10 } # Simplified syntax (PowerShell 3.0+) Get-Process | Where-Object CPU -gt 10 # Multiple conditions with -and Get-Process | Where-Object { $_.CPU -gt 5 -and $_.WorkingSet -gt 50MB } # Multiple conditions with -or Get-Service | Where-Object { $_.Status -eq 'Running' -or $_.StartType -eq 'Automatic' } # Use -match for regex filtering Get-Process | Where-Object { $_.Name -match '^power' } # Use -like for wildcard filtering Get-Service | Where-Object { $_.Name -like '*sql*' } # Filter by property existence Get-ChildItem | Where-Object { $_.PSIsContainer } # Complex filtering with script block Get-ChildItem -Recurse | Where-Object { $_.Extension -eq '.log' -and $_.Length -gt 1MB -and $_.LastWriteTime -lt (Get-Date).AddDays(-30) } ``` ## ForEach-Object - Process Each Pipeline Item The `ForEach-Object` cmdlet performs an operation on each item in the pipeline. It's used for transforming data, executing commands per item, or calling methods on objects. ```powershell # Basic iteration 1..5 | ForEach-Object { $_ * 2 } # Output: 2, 4, 6, 8, 10 # Access current object with $_ Get-Process | ForEach-Object { $_.Name.ToUpper() } # Call methods on each object Get-Service -Name wuauserv | ForEach-Object { $_.Start() } # Multiple operations per item Get-Content servers.txt | ForEach-Object { $result = Test-Connection -ComputerName $_ -Count 1 -Quiet [PSCustomObject]@{ Server = $_ Online = $result CheckTime = Get-Date } } # Parallel processing (PowerShell 7+) 1..10 | ForEach-Object -Parallel { Start-Sleep -Seconds 1 "Processed $_" } -ThrottleLimit 5 # Using Begin, Process, End blocks Get-Process | ForEach-Object -Begin { $count = 0 } -Process { $count++ } -End { "Total processes: $count" } ``` ## Sort-Object - Order Pipeline Results The `Sort-Object` cmdlet sorts objects by property values. It supports ascending/descending order, multiple sort properties, and custom sort expressions. ```powershell # Sort by single property (ascending) Get-Process | Sort-Object -Property CPU # Sort descending Get-Process | Sort-Object -Property CPU -Descending # Sort by multiple properties Get-Process | Sort-Object -Property @{Expression='CPU';Descending=$true}, @{Expression='Name';Ascending=$true} # Sort and get unique values Get-Process | Sort-Object -Property Name -Unique # Case-sensitive sort 'apple','Apple','APPLE' | Sort-Object -CaseSensitive # Sort by calculated expression Get-ChildItem | Sort-Object { $_.Name.Length } # Stable sort (preserve original order for equal items) Get-Process | Sort-Object -Property CPU -Stable # Top 10 memory consumers Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 10 ``` ## Group-Object - Aggregate Data by Property The `Group-Object` cmdlet groups objects that have the same value for specified properties. It's useful for counting, categorizing, and summarizing data. ```powershell # Group processes by name Get-Process | Group-Object -Property Name # Get counts only Get-Process | Group-Object -Property Name -NoElement # Group files by extension Get-ChildItem -File | Group-Object -Property Extension | Sort-Object Count -Descending # Group and analyze Get-Service | Group-Object -Property Status | ForEach-Object { [PSCustomObject]@{ Status = $_.Name Count = $_.Count Services = ($_.Group.Name -join ', ') } } # Group by calculated property Get-ChildItem -File | Group-Object { if ($_.Length -lt 1KB) { 'Tiny' } elseif ($_.Length -lt 1MB) { 'Small' } elseif ($_.Length -lt 100MB) { 'Medium' } else { 'Large' } } # Create hashtable from grouped data $processTable = Get-Process | Group-Object -Property Name -AsHashTable $processTable['powershell'] ``` ## Measure-Object - Calculate Statistics The `Measure-Object` cmdlet calculates statistics for numeric properties including count, sum, average, minimum, and maximum values. ```powershell # Count items Get-Process | Measure-Object # Sum a property Get-Process | Measure-Object -Property WorkingSet -Sum # All statistics Get-Process | Measure-Object -Property CPU -Average -Maximum -Minimum -Sum # Count characters, words, lines in text Get-Content -Path C:\data\document.txt | Measure-Object -Character -Word -Line # Calculate file size statistics Get-ChildItem -Recurse -File | Measure-Object -Property Length -Sum -Average -Maximum # Output: # Count : 150 # Average : 1048576 # Sum : 157286400 # Maximum : 52428800 # Minimum : # Property : Length # Format the results $stats = Get-ChildItem -Recurse -File | Measure-Object -Property Length -Sum "Total size: {0:N2} MB" -f ($stats.Sum / 1MB) ``` ## Hashtables - Key-Value Data Structures Hashtables are fundamental data structures in PowerShell for storing key-value pairs. They're used extensively for parameters, lookups, and data organization. ```powershell # Create empty hashtable $hash = @{} # Create hashtable with values $person = @{ Name = 'John Doe' Age = 30 City = 'Seattle' } # Access values $person['Name'] # Using bracket notation $person.Name # Using dot notation # Add or update values $person['Email'] = 'john@example.com' $person.Phone = '555-1234' # Remove a key $person.Remove('Phone') # Check if key exists $person.ContainsKey('Name') # Returns: True # Iterate over hashtable $person.GetEnumerator() | ForEach-Object { "$($_.Key): $($_.Value)" } # Use as lookup table $serverEnvironments = @{ 'srv-prod-01' = 'Production' 'srv-dev-01' = 'Development' 'srv-test-01' = 'Testing' } $serverEnvironments['srv-prod-01'] # Returns: Production # Splatting parameters with hashtable $params = @{ Path = 'C:\logs' Filter = '*.log' Recurse = $true } Get-ChildItem @params # Ordered hashtable (preserves insertion order) $ordered = [ordered]@{ First = 1 Second = 2 Third = 3 } ``` ## Arrays - Collections of Objects Arrays store collections of objects and support various operations for manipulation and iteration. PowerShell arrays are flexible and can contain mixed types. ```powershell # Create an array $numbers = @(1, 2, 3, 4, 5) # Create array with range operator $range = 1..10 # Empty array $empty = @() # Access elements (zero-based index) $numbers[0] # First element: 1 $numbers[-1] # Last element: 5 $numbers[1..3] # Elements 2-4: 2, 3, 4 # Add elements $numbers += 6 $numbers = $numbers + @(7, 8, 9) # Array length $numbers.Count $numbers.Length # Check if contains value $numbers -contains 5 # Returns: True 5 -in $numbers # Returns: True # Filter array $numbers | Where-Object { $_ -gt 5 } # Transform array $numbers | ForEach-Object { $_ * 2 } # ArrayList for better performance with modifications $list = [System.Collections.ArrayList]@() $list.Add('item1') | Out-Null $list.AddRange(@('item2', 'item3')) $list.Remove('item1') # Generic List (type-safe) $stringList = [System.Collections.Generic.List[string]]::new() $stringList.Add('Hello') $stringList.Add('World') ``` ## PSCustomObject - Create Custom Objects `PSCustomObject` creates lightweight custom objects with defined properties. It's the standard way to create structured data in PowerShell. ```powershell # Create custom object $server = [PSCustomObject]@{ Name = 'srv-web-01' IP = '192.168.1.100' Role = 'WebServer' Status = 'Online' } # Access properties $server.Name $server.IP # Add property to existing object $server | Add-Member -NotePropertyName 'LastCheck' -NotePropertyValue (Get-Date) # Create objects in a pipeline $servers = @('srv-01', 'srv-02', 'srv-03') | ForEach-Object { [PSCustomObject]@{ ServerName = $_ Pingable = Test-Connection -ComputerName $_ -Count 1 -Quiet -ErrorAction SilentlyContinue CheckTime = Get-Date } } # Export to CSV $servers | Export-Csv -Path C:\output\servers.csv -NoTypeInformation # Create from hashtable dynamically $properties = @{ ComputerName = $env:COMPUTERNAME OS = (Get-CimInstance Win32_OperatingSystem).Caption Memory = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory } $systemInfo = [PSCustomObject]$properties ``` ## Try-Catch-Finally - Exception Handling PowerShell uses try-catch-finally blocks for structured exception handling. This allows graceful handling of errors and ensures cleanup code runs. ```powershell # Basic try-catch try { $result = Get-Content -Path 'C:\nonexistent.txt' -ErrorAction Stop } catch { Write-Warning "Error: $_" } # Catch specific exception types try { $connection = [System.Data.SqlClient.SqlConnection]::new($connectionString) $connection.Open() } catch [System.Data.SqlClient.SqlException] { Write-Error "SQL Error: $($_.Exception.Message)" } catch [System.Exception] { Write-Error "General Error: $($_.Exception.Message)" } # Try-catch-finally for cleanup $file = $null try { $file = [System.IO.StreamWriter]::new('C:\output\data.txt') $file.WriteLine('Important data') } catch { Write-Error "Failed to write file: $_" } finally { if ($file) { $file.Close() $file.Dispose() } } # Access error details try { Get-Process -Name 'NonExistentProcess' -ErrorAction Stop } catch { Write-Host "Exception Type: $($_.Exception.GetType().FullName)" Write-Host "Exception Message: $($_.Exception.Message)" Write-Host "Script Stack Trace: $($_.ScriptStackTrace)" } # Throw custom exception function Test-Requirement { param([string]$Path) if (-not (Test-Path $Path)) { throw [System.IO.FileNotFoundException]::new("Required file not found: $Path") } } ``` ## Invoke-Command - Remote Command Execution The `Invoke-Command` cmdlet runs commands on local and remote computers using PowerShell remoting. It enables one-to-many remote administration. ```powershell # Run command on remote computer Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Process | Where-Object CPU -gt 100 } # Run on multiple computers Invoke-Command -ComputerName Server01, Server02, Server03 -ScriptBlock { Get-Service -Name W32time } # Use credentials $cred = Get-Credential Invoke-Command -ComputerName Server01 -Credential $cred -ScriptBlock { Restart-Service -Name Spooler } # Pass variables to remote session $serviceName = 'W32time' Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Service -Name $using:serviceName } # Create persistent session for multiple commands $session = New-PSSession -ComputerName Server01 -Credential $cred Invoke-Command -Session $session -ScriptBlock { Get-Process } Invoke-Command -Session $session -ScriptBlock { Get-Service } Remove-PSSession $session # Run script file on remote computer Invoke-Command -ComputerName Server01 -FilePath C:\Scripts\Maintenance.ps1 # Parallel execution on many servers $servers = Get-Content C:\servers.txt Invoke-Command -ComputerName $servers -ScriptBlock { [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME FreeSpaceGB = [math]::Round((Get-PSDrive C).Free / 1GB, 2) Uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime } } -ThrottleLimit 50 ``` ## Enter-PSSession - Interactive Remote Session The `Enter-PSSession` cmdlet starts an interactive session with a single remote computer. You work directly on the remote machine as if you were logged in locally. ```powershell # Start interactive session Enter-PSSession -ComputerName Server01 # With credentials $cred = Get-Credential Enter-PSSession -ComputerName Server01 -Credential $cred # Using SSH (PowerShell 7+) Enter-PSSession -HostName user@server01 -SSHTransport # When connected, prompt changes to show remote computer: # [Server01]: PS C:\Users\Admin> # Run commands on remote computer [Server01]: PS> Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 [Server01]: PS> Get-EventLog -LogName System -Newest 10 [Server01]: PS> Get-Service | Where-Object Status -eq 'Running' # Exit the remote session [Server01]: PS> Exit-PSSession # Or use the Exit command [Server01]: PS> exit ``` ## Functions - Create Reusable Commands Functions encapsulate reusable code with parameters, pipeline support, and help documentation. Advanced functions provide cmdlet-like features. ```powershell # Simple function function Get-Greeting { param([string]$Name = 'World') "Hello, $Name!" } Get-Greeting -Name 'PowerShell' # Function with multiple parameters function Get-ServerInfo { param( [Parameter(Mandatory)] [string]$ComputerName, [ValidateSet('Basic', 'Detailed')] [string]$Level = 'Basic' ) $os = Get-CimInstance -ComputerName $ComputerName -ClassName Win32_OperatingSystem [PSCustomObject]@{ ComputerName = $ComputerName OS = $os.Caption LastBoot = $os.LastBootUpTime } } # Advanced function with pipeline support function Test-ServerConnection { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('CN', 'Server')] [string[]]$ComputerName, [int]$Count = 2, [switch]$Detailed ) process { foreach ($computer in $ComputerName) { $pingResult = Test-Connection -ComputerName $computer -Count $Count -Quiet [PSCustomObject]@{ ComputerName = $computer Online = $pingResult CheckTime = Get-Date } } } } # Use the function 'Server01', 'Server02' | Test-ServerConnection -Count 3 # Function with error handling function Get-DiskSpace { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$ComputerName ) try { $disk = Get-CimInstance -ComputerName $ComputerName -ClassName Win32_LogicalDisk -Filter "DriveType=3" -ErrorAction Stop $disk | ForEach-Object { [PSCustomObject]@{ ComputerName = $ComputerName Drive = $_.DeviceID SizeGB = [math]::Round($_.Size / 1GB, 2) FreeGB = [math]::Round($_.FreeSpace / 1GB, 2) PercentFree = [math]::Round(($_.FreeSpace / $_.Size) * 100, 2) } } } catch { Write-Error "Failed to get disk info from $ComputerName : $_" } } ``` ## Modules - Organize and Share Code PowerShell modules package related functions, cmdlets, and resources for easy distribution and reuse. They enable code organization and sharing via repositories like PowerShell Gallery. ```powershell # List installed modules Get-Module -ListAvailable # Import a module Import-Module -Name ActiveDirectory # View commands in a module Get-Command -Module ActiveDirectory # Find modules in PowerShell Gallery Find-Module -Name '*Azure*' | Select-Object Name, Version, Description # Install module from PowerShell Gallery Install-Module -Name Az -Scope CurrentUser -Force # Update installed module Update-Module -Name Az # Remove module from session Remove-Module -Name ActiveDirectory # Create a simple script module (Save as MyModule.psm1) # Contents of MyModule.psm1: function Get-SystemUptime { $os = Get-CimInstance Win32_OperatingSystem $uptime = (Get-Date) - $os.LastBootUpTime [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME LastBoot = $os.LastBootUpTime Uptime = "{0} days, {1} hours" -f $uptime.Days, $uptime.Hours } } Export-ModuleMember -Function Get-SystemUptime # Import custom module Import-Module -Name C:\Modules\MyModule.psm1 # View module details Get-Module -Name MyModule | Format-List ``` ## ConvertTo-Json, ConvertFrom-Json - JSON Data Handling These cmdlets convert PowerShell objects to JSON format and parse JSON text into objects, enabling integration with web APIs and configuration files. ```powershell # Convert object to JSON $data = @{ Name = 'Server01' IP = '192.168.1.100' Roles = @('Web', 'Database') Config = @{ MaxConnections = 100 Timeout = 30 } } $data | ConvertTo-Json -Depth 3 # Output: # { # "Name": "Server01", # "IP": "192.168.1.100", # "Roles": ["Web", "Database"], # "Config": { # "MaxConnections": 100, # "Timeout": 30 # } # } # Convert JSON to object $json = '{"Name":"John","Age":30,"Active":true}' $obj = $json | ConvertFrom-Json $obj.Name # Returns: John # Read JSON file $config = Get-Content -Path 'config.json' -Raw | ConvertFrom-Json # Write JSON file $data | ConvertTo-Json -Depth 5 | Set-Content -Path 'output.json' # Work with REST API $response = Invoke-RestMethod -Uri 'https://api.github.com/users/microsoft' $response | ConvertTo-Json -Depth 2 # Handle JSON arrays $jsonArray = '[{"id":1,"name":"Item1"},{"id":2,"name":"Item2"}]' $items = $jsonArray | ConvertFrom-Json $items | ForEach-Object { $_.name } ``` ## Invoke-RestMethod - Call Web APIs The `Invoke-RestMethod` cmdlet sends HTTP requests to RESTful web services and automatically parses JSON/XML responses into PowerShell objects. ```powershell # Simple GET request $response = Invoke-RestMethod -Uri 'https://api.github.com/users/microsoft' $response.name $response.public_repos # GET with query parameters $params = @{ Uri = 'https://api.example.com/search' Method = 'Get' Body = @{ query = 'PowerShell' limit = 10 } } $results = Invoke-RestMethod @params # POST request with JSON body $body = @{ title = 'New Post' content = 'Hello World' author = 'PowerShell User' } | ConvertTo-Json $response = Invoke-RestMethod -Uri 'https://api.example.com/posts' ` -Method Post ` -Body $body ` -ContentType 'application/json' # Using authentication $headers = @{ 'Authorization' = "Bearer $token" 'Accept' = 'application/json' } $response = Invoke-RestMethod -Uri 'https://api.example.com/secure' -Headers $headers # Handle pagination $allResults = @() $page = 1 do { $response = Invoke-RestMethod -Uri "https://api.example.com/items?page=$page" $allResults += $response.items $page++ } while ($response.hasMore) # Error handling with REST calls try { $response = Invoke-RestMethod -Uri 'https://api.example.com/data' -ErrorAction Stop } catch { $statusCode = $_.Exception.Response.StatusCode.value__ Write-Error "API call failed with status $statusCode" } ``` ## Get-CimInstance - Query System Information The `Get-CimInstance` cmdlet retrieves WMI class instances, providing access to detailed system hardware and software information across local and remote systems. ```powershell # Get operating system information Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, LastBootUpTime, FreePhysicalMemory # Get computer system info Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Name, Domain, TotalPhysicalMemory, NumberOfProcessors # Get disk information Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{N='SizeGB';E={[math]::Round($_.Size/1GB,2)}}, @{N='FreeGB';E={[math]::Round($_.FreeSpace/1GB,2)}} # Get network adapter configuration Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled=$true" | Select-Object Description, IPAddress, DefaultIPGateway, DNSServerSearchOrder # Query remote computer Get-CimInstance -ComputerName Server01 -ClassName Win32_Service | Where-Object State -eq 'Running' | Select-Object Name, DisplayName, StartMode # Get installed software Get-CimInstance -ClassName Win32_Product | Select-Object Name, Version, Vendor | Sort-Object Name # Get processor information Get-CimInstance -ClassName Win32_Processor | Select-Object Name, NumberOfCores, MaxClockSpeed # List all available WMI classes Get-CimClass -Namespace root/cimv2 | Where-Object CimClassName -like 'Win32_*' ``` ## Start-Job, Get-Job - Background Jobs PowerShell jobs run commands asynchronously in the background, allowing you to continue working while long-running tasks execute. ```powershell # Start a background job $job = Start-Job -ScriptBlock { Get-ChildItem -Path C:\ -Recurse -File | Measure-Object -Property Length -Sum } # Check job status Get-Job # Get job results (wait for completion) $result = Receive-Job -Job $job -Wait # Start multiple jobs $jobs = foreach ($server in @('Server01', 'Server02', 'Server03')) { Start-Job -Name "Check-$server" -ScriptBlock { param($ComputerName) Test-Connection -ComputerName $ComputerName -Count 3 } -ArgumentList $server } # Wait for all jobs to complete $jobs | Wait-Job # Get all results $jobs | Receive-Job # Remove completed jobs Get-Job -State Completed | Remove-Job # Job with timeout $job = Start-Job -ScriptBlock { Start-Sleep -Seconds 300 } $completed = Wait-Job -Job $job -Timeout 60 if (-not $completed) { Stop-Job -Job $job Write-Warning "Job timed out" } Remove-Job -Job $job # Using thread jobs (faster, PowerShell 7+) $threadJob = Start-ThreadJob -ScriptBlock { 1..1000 | ForEach-Object { $_ * 2 } } $threadJob | Wait-Job | Receive-Job ``` ## Summary PowerShell provides a comprehensive automation platform combining an interactive shell with a full-featured scripting language. Key capabilities include object-based pipeline processing, remote management via PowerShell remoting, extensive cmdlet libraries for system administration, and seamless integration with .NET and REST APIs. The modular architecture enables code reuse through functions and modules, while the PowerShell Gallery provides access to thousands of community-contributed solutions. Common integration patterns include automating server management with `Invoke-Command` across multiple systems, building deployment pipelines using scripts and modules, querying and transforming data with the pipeline operators (`Where-Object`, `ForEach-Object`, `Select-Object`), and integrating with web services via `Invoke-RestMethod`. The consistent Verb-Noun naming convention and rich help system make it accessible to newcomers while providing the depth needed for complex automation scenarios. Whether managing Windows servers, Azure resources, or cross-platform Linux systems, PowerShell serves as a unified automation tool for modern IT operations.