As organizations automate infrastructure management, cloud operations, and system administration, recruiters must identify PowerShell professionals who can streamline operations through scripting and automation. With expertise in Windows administration, Azure automation, and cross-platform scripting, PowerShell specialists play a critical role in modern IT and DevOps environments.
This resource, "100+ PowerShell Interview Questions and Answers," is tailored for recruiters to simplify the evaluation process. It covers a wide range of topics—from PowerShell fundamentals to advanced automation and scripting practices, including cmdlets, pipelines, modules, and DSC.
Whether you're hiring System Administrators, DevOps Engineers, Cloud Engineers, or IT Automation Specialists, this guide enables you to assess a candidate’s:
For a streamlined assessment process, consider platforms like WeCP, which allow you to:
Save time, enhance your hiring process, and confidently hire PowerShell professionals who can automate, manage, and scale IT operations from day one.
PowerShell is a task automation and configuration management framework created by Microsoft.
It consists of:
PowerShell is object-oriented, meaning every output is a .NET object. These objects can be passed between commands through the pipeline, allowing for complex automation workflows.
How it differs from Command Prompt (CMD):
FeaturePowerShellCommand PromptOutput.NET objectsPlain textScriptingFull scripting languageBasic batch scriptsExtensibilitySupports modules, functions, classesVery limitedIntegrationDeep integration with Windows OS, WMI, CIM, .NETVery limitedRemote managementSupports PowerShell RemotingNo native remotingAutomationEnterprise-grade automationBasic task execution
PowerShell is designed for system administrators, DevOps engineers, and automation tasks, whereas CMD is suitable only for basic command execution.
A PowerShell cmdlet (pronounced command-let) is a lightweight, specialized .NET class that performs a specific action.
Cmdlets are the core building blocks of PowerShell.
Key characteristics:
Get-Process, Set-Service).-Verbose, -ErrorAction, -Debug.Cmdlets are more powerful than traditional shell commands since they work with structured data, making automation more reliable.
PowerShell enforces a standard naming format:
Example:
Get-Service
Set-ExecutionPolicy
New-Item
Remove-Process
Get-Command -Verb or -Noun.Get – retrieve dataSet – modify somethingNew – create somethingRemove – delete somethingStart – begin executionStop – end executionProcess, Service, Item, User.
This structure greatly improves readability and predictability in scripting.
PowerShell ISE (Integrated Scripting Environment) is a graphical editor provided by Microsoft for writing, testing, and debugging PowerShell scripts.
Key features:
ISE makes script development more efficient, especially for beginners.
Although ISE is deprecated in favor of Visual Studio Code, it is still widely used on Windows systems for quick script creation and testing.
A PowerShell module is a package that contains PowerShell cmdlets, functions, scripts, DSC resources, or other components grouped together for reuse.
Modules make it easier to:
Module types include:
.psm1).dll).psd1)Modules are stored in locations such as:
C:\Program Files\WindowsPowerShell\ModulesC:\Windows\System32\WindowsPowerShell\v1.0\ModulesThey are loaded automatically when a cmdlet inside them is used (module auto-loading).
You use the Get-Command cmdlet to list all cmdlets available in the current PowerShell session.
Example:
Get-Command
You can filter results:
Get-Command -CommandType Cmdlet
List all commands containing “Service”:
Get-Command *Service*
List commands from a specific module:
Get-Command -Module Microsoft.PowerShell.Management
Get-Command provides a comprehensive view of all executable components in PowerShell, including functions, aliases, workflows, and applications.
Get-Help displays detailed documentation for cmdlets, functions, modules, scripts, and concepts in PowerShell.
It helps users understand:
Example:
Get-Help Get-Process
More detailed help:
Get-Help Get-Process -Detailed
Show full examples:
Get-Help Get-Process -Examples
Get-Help is essential for learning and mastering PowerShell since all commands follow a standard documentation format.
You use the Update-Help cmdlet.
Example:
Update-Help
This command downloads the latest help files from Microsoft and installs them locally.
If you want help for a specific module:
Update-Help -Module Microsoft.PowerShell.Management
If running with restricted permissions:
Update-Help -Force
For offline environments:
Save-HelpUpdate-Help -SourcePathKeeping help updated ensures access to the most accurate and latest documentation.
Get-Command is used to discover all commands available in PowerShell. It is one of the most important cmdlets during learning and troubleshooting.
It shows:
Examples:
Get-Command -CommandType Cmdlet
Find commands by verb:
Get-Command -Verb Get
Find commands by noun:
Get-Command -Noun Service
It is often used for discovery when you don’t know the exact command name but know what action you want to perform.
PowerShell providers are interfaces that allow access to different data stores in a uniform way, as if they were file systems.
Providers let you navigate and manipulate items such as:
For example:
cd HKLM:\Software → navigate registry like foldersGet-ChildItem Env: → list environment variablesGet-ChildItem Cert:\ → browse certificatesEssentially, providers abstract complex data sources into a consistent structure, enabling easier scripting and automation.
In PowerShell, the pipeline (|) is one of the most powerful features because it passes objects, not text, from one command to another.
This is a major difference from traditional shells (like CMD or Bash), which only pass raw text.
When you use the pipeline:
Example:
Get-Process | Where-Object { $_.CPU -gt 50 }
Here:
Get-Process outputs process objects.Where-Object, which filters based on CPU usage.Benefits of the PowerShell pipeline:
In PowerShell, variables are assigned using the dollar sign ($) followed by the variable name.
Syntax:
$variableName = value
PowerShell variables are:
$Name and $name are same)Examples:
$name = "Aman"
$age = 25
$numbers = 1,2,3,4,5
$details = Get-Service
Variables can store:
PowerShell automatically interprets the variable’s type based on its assigned value.
In PowerShell, single quotes and double quotes work differently when handling variables and escape sequences.
Example:
$name = "Aman"
'Hello $name'
Output:
Hello $name
" or `n (newline)Example:
"Hello $name"
Output:
Hello Aman
You can check your PowerShell version using built-in variables and cmdlets.
Most common method:
$PSVersionTable
This displays a table containing:
Example:
$PSVersionTable.PSVersion
Alternative commands:
Get-Host
or
$host.version
PowerShell 7+ also supports:
pwsh --version
These methods help identify compatibility for scripts, modules, and features.
Get-Service retrieves information about services installed on a Windows system.
It helps administrators:
Example:
Get-Service
To find a specific service:
Get-Service -Name wuauserv
To filter running services:
Get-Service | Where-Object {$_.Status -eq 'Running'}
The output is a ServiceController object, which provides detailed service information.
PowerShell provides dedicated cmdlets to control Windows services:
Start-Service -Name "wuauserv"
Stop a service
Stop-Service -Name "wuauserv"
Restart a service
Restart-Service -Name "wuauserv"
Check status before starting
(Get-Service -Name "wuauserv").Status
PowerShell ensures safe service control with options like:
-Force to stop dependent servicesGet-Service Spooler | Stop-Service
Services can also be automated in scripts for maintenance and deployment tasks.
The cmdlet used is:
Get-Process
It lists all processes currently running on the system.
Common usage:
Get-Process | Sort-Object CPU -Descending
To find a process by name:
Get-Process -Name "chrome"
To list only specific properties:
Get-Process | Select-Object Name, Id, CPU, StartTime
PowerShell returns process objects, which can be filtered, sorted, or piped into other commands such as:
Stop-Process -Id 1234
Get-Process is widely used for performance monitoring, automation, and troubleshooting.
The primary cmdlet for retrieving event logs is:
Get-EventLog
Example:
Get-EventLog -LogName Application -Newest 20
However, it is older and Windows-specific.
The modern and recommended cmdlet is:
Get-WinEvent
Why Get-WinEvent is preferred:
Example:
Get-WinEvent -LogName Security
Filtering by event ID:
Get-WinEvent -FilterHashtable @{LogName='System'; Id=10016}
This cmdlet is essential for auditing, diagnostics, and monitoring.
Get-ExecutionPolicy shows the current execution policy that controls how PowerShell handles script execution.
Example:
Get-ExecutionPolicy
Possible policies:
Execution policy is a security layer, not a hardened protection mechanism.
It prevents accidental execution of untrusted scripts.
You use the Set-ExecutionPolicy cmdlet.
Basic syntax:
Set-ExecutionPolicy RemoteSigned
To force the change:
Set-ExecutionPolicy RemoteSigned -Force
To apply only to the current user:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Scopes include:
Example for temporary change (session only):
Set-ExecutionPolicy Bypass -Scope Process
Changing execution policy requires understanding security implications, especially when running downloaded scripts.
To create a new directory (folder) in PowerShell, you can use either of the following cmdlets:
New-Item -ItemType Directory -Path "C:\MyFolder"
This command explicitly tells PowerShell to create a directory-type item.
mkdir C:\MyFolder
3. New-Item with recursive creation
New-Item -ItemType Directory -Path "C:\Data\Logs\2024" -Force
-Force ensures nested directories are created even if some exist."One","Two","Three" | ForEach-Object { New-Item -ItemType Directory -Path "C:\Test\$_" }
This flexibility helps in automation scenarios where dynamic folder structures must be created.
To list files in a folder, PowerShell uses the Get-ChildItem cmdlet.
Basic usage:
Get-ChildItem -Path "C:\MyFolder"
Alias:
ls C:\MyFolder
List only files (not folders)
Get-ChildItem -Path "C:\MyFolder" -File
List all files including hidden and system files
Get-ChildItem -Path "C:\MyFolder" -Force
List files recursively
Get-ChildItem -Path "C:\MyFolder" -Recurse
Filter files by extension
Get-ChildItem "C:\MyFolder" -Filter *.txt
PowerShell returns FileInfo objects, allowing further filtering, sorting, or exporting.
Get-Content is used to read the contents of:
Basic usage:
Get-Content -Path "C:\MyFile.txt"
Read last 10 lines:
Get-Content file.txt -Tail 10
Read file in real time (like Linux tail -f):
Get-Content file.txt -Wait
Read file as a single string:
Get-Content file.txt -Raw
Get-Content is essential for log analysis, configuration management, and script automation.
To read CSV files, PowerShell provides the powerful cmdlet:
Import-Csv
Example:
Import-Csv -Path "C:\data\employees.csv"
Example CSV:
Name,Age,City
Aman,25,Delhi
John,30,London
PowerShell usage:
$data = Import-Csv "employees.csv"
$data[0].Name
Filtering
Import-Csv "employees.csv" | Where-Object { $_.Age -gt 28 }
Import-Csv "employees.csv" | Select-Object Name,City
This makes CSV import extremely useful for data manipulation, reporting, and automation tasks.
PowerShell uses the Export-Csv cmdlet to export objects into a CSV format.
Basic usage:
Get-Process | Export-Csv -Path "C:\processes.csv" -NoTypeInformation
-NoTypeInformation removes unwanted metadata.-Append adds data to an existing file.-Force overwrites read-only files.$users = @(
[PSCustomObject]@{Name="Aman"; Age=25}
[PSCustomObject]@{Name="John"; Age=30}
)
$users | Export-Csv "C:\users.csv" -NoTypeInformation
Export selected properties
Get-Service | Select Name,Status | Export-Csv "services.csv" -NoTypeInformation
Export-Csv is widely used for reporting, automation, inventory generation, and audits.
PowerShell supports multiple ways to write output to a file.
"Hello World" | Out-File "C:\test.txt"
2. Set-Content
Set-Content -Path "C:\test.txt" -Value "Hello World"
3. Add-Content (append to existing file)
Add-Content -Path "C:\test.txt" -Value "New line added"
4. Redirect operators
"Hello" > file.txt
"Append this" >> file.txt
Write to console and file at same time:
Get-Process | Tee-Object -FilePath "output.txt"
These commands allow flexible file writing depending on the automation scenario.
Write-Host is used to display output directly to the console, bypassing the PowerShell pipeline.
Example:
Write-Host "Hello World"
Example with color:
Write-Host "Success!" -ForegroundColor Green
Write-Output is usually preferred if output needs to flow through the pipeline.
Read-Host takes input from the user during script execution.
Basic usage:
$name = Read-Host "Enter your name"
Secure input (passwords)
$password = Read-Host "Enter password" -AsSecureString
However, for automation, prompting is discouraged; scripts should be non-interactive.
A PowerShell function is created using the function keyword.
Basic structure:
function SayHello {
Write-Output "Hello!"
}
Calling the function:
SayHello
Function with parameters
function GreetUser {
param(
[string]$Name
)
Write-Output "Hello, $Name!"
}
Calling:
GreetUser -Name "Aman"
Advanced function example
function Get-Square {
[CmdletBinding()]
param([int]$Number)
return ($Number * $Number)
}
Functions improve script reusability and modularity.
A PowerShell script is a .ps1 file that contains a sequence of commands.
Example:Backup.ps1
A function is a block of code defined inside a script or session that performs a specific task.
FunctionScriptReusable code blockIndependent executable fileMust be defined before calling in scriptExecuted as a single fileDoes not need a file extensionRequires .ps1Can be stored in modulesStored as script filesLoaded into memoryRun separately each time
Running a PowerShell script involves understanding execution policy, file path, and script invocation methods.
If your script is in the current directory:
.\scriptname.ps1
PowerShell requires .\ to prevent accidental execution of untrusted scripts.
C:\Scripts\Backup.ps1
3. Run with full path via PowerShell executable
powershell.exe -File "C:\Scripts\Backup.ps1"
4. Run script with parameters
.\Backup.ps1 -Path "C:\Data" -Days 7
5. Run script bypassing policy (session only)
powershell.exe -ExecutionPolicy Bypass -File script.ps1
If you get "script is disabled":
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
.ps1 extension.pwsh instead of powershell.Running scripts is a fundamental skill for automation and task scheduling.
PowerShell Remoting allows you to run PowerShell commands on remote computers.
It uses WS-Management (WinRM) protocol and is essential for automation across multiple machines.
Runs a command on remote computers:
Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Service }
Starts an interactive remote shell:
Enter-PSSession -ComputerName Server01
Enable-PSRemoting
PowerShell Remoting is one of the most powerful features for enterprise management.
Get-Alias displays all aliases defined in the current PowerShell session.
Example:
Get-Alias
Aliases are shortcut names for cmdlets.
Examples:
AliasCmdletlsGet-ChildItemcpCopy-ItemmvMove-ItemrmRemove-Item
Get-Alias ls
Filtering by cmdlet
Get-Alias -Definition Get-Process
Aliases make PowerShell more user-friendly, especially for those familiar with Linux or CMD.
You create a custom alias using the Set-Alias cmdlet.
Example:
Set-Alias -Name gs -Value Get-Service
Now typing:
gs
Executes:
Get-Service
Alias for your own functions
function SayHello { Write-Output "Hello!" }
Set-Alias hi SayHello
Aliases defined with Set-Alias exist only for the session.
To make them permanent, add them to your PowerShell profile:
Set-Alias gs Get-Service
inside:
$PROFILE
Tab completion is a PowerShell usability feature that helps you automatically complete:
When typing a command, pressing TAB cycles through available matches.
Examples:
Typing:
Get-Ser[TAB]
Completes to:
Get-Service
File path completion
cd C:\Prog[TAB]
Expands to:
C:\Program Files
Parameter completion
Get-Process -N[TAB]
Becomes:
Get-Process -Name
Tab completion is one of the best features for beginners and experts alike.
PowerShell scripts can be stopped using several methods depending on how they are running.
Press:
Ctrl + C
This immediately stops script execution.
Use:
break
or
return
or forcefully:
throw "Stopping script!"
4. Kill a running PowerShell process
Stop-Process -Name powershell
5. Stop long running loops
Ctrl + Break
Stopping scripts is important for error handling, debugging, and safely terminating automation tasks.
Clear-Host (alias: cls) clears the PowerShell console screen.
Example:
Clear-Host
It's a simple but helpful cmdlet for maintaining a clean workspace.
PowerShell accesses environment variables through the Env: provider.
Get-ChildItem Env:
2. View specific variable
$Env:PATH
3. Set a new environment variable
$Env:MyVariable = "TestValue"
4. Remove an environment variable
Remove-Item Env:MyVariable
Filtering
Get-ChildItem Env: | Where-Object { $_.Name -like "*PATH*" }
Environment variables are used for configuring application paths, credentials, system settings, and automation tasks.
PowerShell modules can be installed from the PowerShell Gallery using Install-Module.
Example:
Install-Module -Name Az
Install with admin rights
Install-Module -Name PSReadLine -Scope AllUsers
Install without admin rights
Install-Module -Name PSReadLine -Scope CurrentUser
Update a module
Update-Module -Name Az
Find available modules
Find-Module -Name *Azure*
PowerShellGet module must be installed and configured.
Module installation allows extending PowerShell functionality with:
A PowerShell profile is a startup script that runs every time a new PowerShell session opens.
It allows you to personalize and configure your environment.
View profile path:
$PROFILE
Set-Alias ll Get-ChildItem
Import-Module Az
function Hello { Write-Output "Welcome, Aman!" }
Profiles are extremely useful for building a productive and personalized automation environment.
PowerShell 5.1 and PowerShell 7 differ significantly in platform support, performance, architecture, and capabilities.
1..10 | ForEach-Object -Parallel { $_ * 2 }
Ternary conditional operator
$result = $age -gt 18 ? "Adult" : "Minor"
Null-coalescing operator
$message = $value ?? "DefaultValue"
Summary:
PowerShell 7 is faster, cross-platform, modern, and more powerful, while PowerShell 5.1 remains essential for legacy Windows modules.
Common parameters are automatically available in almost all PowerShell cmdlets, functions, and scripts.
They allow consistency across commands and provide advanced control for:
ParameterPurpose-VerboseShows detailed internal operation messages-DebugPrompts for debug information-ErrorActionControls error behavior (Continue, Stop, Silence, Ignore)-ErrorVariableStores errors in a variable-OutVariableStores output in a variable-OutBufferControls paging output-WarningActionControls warnings
Example:
Get-Service -Verbose
Common parameters are implemented via PowerShell’s CmdletBinding attribute and inherited by most commands.
PowerShell’s pipeline does not pass plain text—it passes .NET objects.
Get-Process
Where-Object { $_.CPU -gt 10 }
Example:
Get-Service | Stop-Service
Here, Get-Service outputs a ServiceController object.Stop-Service accepts InputObject, so pipeline binding works.
An advanced function is a PowerShell function that behaves like a full cmdlet.
It includes:
Example:
function Get-UserInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name
)
Write-Output "User: $Name"
}
-Verbose, -Debug, -ErrorActionValidateSet, ValidateRange)Advanced functions are building blocks for professional modules.
Enables cmdlet-like behavior in functions.
Example:
[CmdletBinding()]
What it enables:
Used to define metadata for parameters.
Example:
[Parameter(Mandatory, ValueFromPipeline)]
[string]$Name
Properties of Parameter Attribute:
These attributes make functions powerful and professional-grade.
PowerShell parameters can be configured to behave in multiple ways.
Require user input.
param(
[Parameter(Mandatory)]
$Name
)
If not supplied, PowerShell prompts the user.
Users don't need to type the parameter name.
Get-Process chrome
Instead of:
Get-Process -Name chrome
You define a positional index:
[Parameter(Position=0)]
Accepts entire objects.
[Parameter(ValueFromPipeline)]
$InputObject
Example:
Get-Service | Stop-Service
Property matches parameter name.
[Parameter(ValueFromPipelineByPropertyName)]
[string]$Name
Matches when object contains .Name.
These parameter types control how flexible and user-friendly functions and cmdlets can be.
Splatting allows you to pass a set of parameters to a cmdlet/function using a hashtable or an array, instead of typing each parameter manually.
$params = @{
Name = "Aman"
Age = 25
City = "Delhi"
}
New-User @params
Array splatting (positional parameters)
$args = "Aman", 25, "Delhi"
New-User @args
Splatting is especially useful in complex scripts and automation frameworks.
PowerShell supports structured error handling similar to other programming languages.
try {
# Code that may fail
}
catch {
# Handling error
}
finally {
# Always runs
}
Example
try {
Get-Item "C:\missingfile.txt" -ErrorAction Stop
}
catch {
Write-Output "File not found!"
}
finally {
Write-Output "Operation complete."
}
-ErrorAction Stop to convert non-terminating errors into terminating ones.catch [System.IO.FileNotFoundException]
Try/Catch/Finally creates robust, fault-tolerant scripts.
Write-Host "Hello" -ForegroundColor Yellow
Write-Output "Hello"
-Verbose.Write-Verbose "Processing file..."
Calling:
Get-Data -Verbose
CmdletGoes to PipelineRequires SwitchUse CaseWrite-Host❌ No❌Console UIWrite-Output✔ Yes❌Actual script outputWrite-Verbose❌ No✔ Yes (-Verbose)Debugging, logging
$ErrorActionPreference controls how PowerShell handles non-terminating errors.
ValueMeaningContinue (default)Show error, continue executionStopConvert all errors into terminating errorsSilentlyContinueSuppress error messagesIgnoreIgnore completely (no error logged)InquireAsk user what to doSuspendUsed in workflows
$ErrorActionPreference = "Stop"
Get-Item "C:\nofile.txt"
Now the script halts on error.
Get-Item "C:\nofile.txt" -ErrorAction SilentlyContinue
$ErrorActionPreference is essential for controlling script behavior in error-prone environments.
PowerShell’s pipeline is fundamentally different from traditional shells (like CMD or Bash). Instead of passing text between commands, PowerShell passes rich .NET objects.
Get-Process
Get-Service | Where-Object { $_.Status -eq "Running" } | Select-Object Name,Status
Each stage receives structured objects, enabling powerful filtering, transformation, and reporting.
PowerShell includes formatting cmdlets used to control how output appears on the screen.
Displays data in a row-and-column table.
Example:
Get-Process | Format-Table Name, CPU, Id
Useful for:
Displays each object in a property-per-line format.
Example:
Get-Service | Format-List *
Useful when:
Wrong:
Get-Service | Format-Table | Export-Csv
Format cmdlets produce formatting instructions, not raw objects—so they break downstream commands.
Correct:
Get-Service | Select Name,Status | Export-Csv file.csv
Both are used for filtering, but they differ in performance and how they execute.
Executed after the cmdlet has retrieved all objects.
Syntax:
Get-Process | Where-Object { $_.CPU -gt 10 }
Characteristics:
Executed before objects enter the pipeline.
Example:
Get-ADUser -Filter { Name -like "*John*" }
Get-ChildItem -Filter *.txt
Characteristics:
Use CaseRecommendationLarge data setsFilter parameterNeed complex logicWhere-ObjectData source supports filtering (AD, FileSystem)Filter parameterScripted filtering in pipelineWhere-Object
Where-Object = flexible
Filter parameter = faster
A script block is a block of executable code enclosed in {}.
Example:
{ Write-Host "Hello" }
Script blocks are first-class objects, meaning they can be:
$block = { param($x) $x * 2 }
& $block 10
Where-Object { $_.Status -eq "Running" }
In ForEach-Object:
ForEach-Object { $_.Name }
Script blocks provide PowerShell with high flexibility and dynamic execution capabilities.
Calculated properties allow you to create new dynamic properties when using Select-Object or Format cmdlets.
Syntax:
@{Name='NewProperty'; Expression={ <script block> }}
Example 1: Calculate memory in MB
Get-Process | Select-Object Name,
@{Name='MemoryMB'; Expression = { $_.WorkingSet / 1MB }}
Example 2: Full name from first and last
Get-ADUser -Filter * | Select-Object
@{Name='FullName'; Expression={ "$($_.GivenName) $($_.Surname)" }}
Example 3: Status label
Get-Service | Select Name,
@{Name='StatusLabel'; Expression={ if ($_.Status -eq 'Running') {'Active'} else {'Inactive'} }}
Calculated properties are incredibly powerful for reporting, data shaping, and generating custom output.
PowerShell provides cmdlets from the ScheduledTasks module.
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\Backup.ps1"
Step 2: Create a trigger
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
Step 3: Register the scheduled task
Register-ScheduledTask -TaskName "DailyBackup" -Action $action -Trigger $trigger -Description "Daily backup at 3am"
Run as SYSTEM
Register-ScheduledTask -TaskName "MyTask" -Action $action -Trigger $trigger -User "SYSTEM"
View tasks
Get-ScheduledTask
Run immediately
Start-ScheduledTask -TaskName "DailyBackup"
This allows automation of recurring maintenance tasks.
PowerShell Remoting enables executing commands/scripts on remote computers.
It is built on the WinRM (Windows Remote Management) protocol, which uses:
Enable-PSRemoting -Force
PowerShell Remoting is essential for enterprise administration and automation across large environments.
Both are used for remoting, but serve different purposes.
Creates an interactive remote session.
Enter-PSSession -ComputerName Server01
Inside the session, you work as if you are on the remote machine.
Exit using:
Exit-PSSession
Runs a script block non-interactively on one or many remote systems.
Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Service }
Run a script on multiple servers
Invoke-Command -ComputerName Server01, Server02, Server03 -ScriptBlock { hostname }
Pass local variables to remote machine
$Name = "Test"
Invoke-Command -ComputerName Server01 -ScriptBlock { param($x) Write-Output $x } -ArgumentList $Name
Persistent Sessions
$s = New-PSSession -ComputerName Server01
Invoke-Command -Session $s -ScriptBlock { Get-Process }
Remove-PSSession $s
PowerShell supports two execution models:
Example:
Get-Process
Example:
Start-Job -ScriptBlock { Get-Process }
FeatureSynchronousAsynchronousBlockingYesNoOutputImmediateRetrieved laterBest forShort tasksLong-running tasksExecutionSame sessionSeparate process/runspace
PowerShell provides multiple job types:
Here’s how to manage standard background jobs.
Start-Job -ScriptBlock { Get-Process }
Get-Job
3. Receive job output
Receive-Job -Id 1
Receive without removing
Receive-Job -Id 1 -Keep
4. Stop a job
Stop-Job -Id 1
5. Remove a job
Remove-Job -Id 1
6. Wait for job to complete
Wait-Job -Id 1
7. Run multiple background jobs
1..5 | ForEach-Object {
Start-Job -ScriptBlock { Start-Sleep -Seconds 5; $_ }
}
8. Using Thread Jobs (faster and lighter)
Start-ThreadJob -ScriptBlock { Get-Date }
Background jobs are essential for parallelization, large-scale automation, and long-running tasks.
A runspace is the underlying PowerShell execution environment where PowerShell commands are run.
Every PowerShell session consists of at least one runspace, but advanced automation scenarios often require multiple runspaces for parallel execution.
FeatureRunspacesJobsSpeedVery fast (in-memory threads)Slower (child PowerShell process)Resource usageLow (threads)Higher (process-per-job)ComplexityHigherLower
$runspace = [runspacefactory]::CreateRunspace()
$runspace.Open()
Runspaces give developers fine-grained control and better performance than jobs.
Signing a script ensures that it is trusted and has not been modified, especially under stricter execution policies.
Use a trusted CA or create a test certificate:
New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=MyCodeSigning"
Typically stored in Cert:\CurrentUser\My.
Set-AuthenticodeSignature -FilePath "C:\Scripts\Backup.ps1" -Certificate $cert
Set-AuthenticodeSignature -FilePath "C:\Scripts\Backup.ps1" -Certificate $cert
Set-AuthenticodeSignature -FilePath "C:\Scripts\Backup.ps1" -Certificate $cert
Step 4: Verify the signature
Get-AuthenticodeSignature C:\Scripts\Backup.ps1
Script signing is critical in secure and enterprise-based PowerShell environments.
PowerShell execution policies determine how scripts are allowed to run.
Ideal for:
Ideal for:
PolicyLocal ScriptsInternet ScriptsSecurityAllSignedMust be signedMust be signedHighestRemoteSignedAllowed unsignedMust be signedMedium
PowerShell provides two primary cmdlets for working with JSON:
$json = Get-Content "data.json" -Raw
$data = $json | ConvertFrom-Json
$data.Name
$data.Address.City
The result is a custom object with properties matching the JSON keys.
$object | ConvertTo-Json -Depth 5
Depth is important for nested objects.
$person = [PSCustomObject]@{
Name = "Aman"
Age = 25
}
$person | ConvertTo-Json | Set-Content "person.json"
JSON handling is easy and powerful in PowerShell due to native serialization support.
PowerShell can treat XML as a typed .NET XML document, making navigation and manipulation very easy.
[xml]$xml = Get-Content "config.xml"
Access elements
$xml.settings.database.server
Modify XML
$xml.settings.database.server = "NewServer"
$xml.Save("config.xml")
Create XML
$xml = New-Object System.Xml.XmlDocument
$xml.LoadXml("<root><name>Aman</name></root>")
XPath queries
$xml.SelectNodes("//server")
$xml.SelectSingleNode("//database/name")
Convert object to XML
$xml = $object | ConvertTo-Xml
XML is widely used in:
Select-Object is used to select properties or create calculated ones from pipeline objects.
Get-Process | Select-Object Name, Id, CPU
Select first N items
Get-Service | Select-Object -First 5
Use calculated properties
Get-Process | Select-Object Name,
@{Name="MemoryMB"; Expression={ $_.WorkingSet / 1MB }}
Select unique values
Get-ChildItem | Select-Object Extension -Unique
Select-Object does not break objects (unlike Format-Table), so further processing is allowed:
Get-Process | Select Name, Id | Export-Csv file.csv
—
Get-Member reveals the type, properties, and methods of any PowerShell object.
Get-Process | Get-Member
Shows:
(Get-Item C:\test.txt) | Get-Member
Filter members
Get-Service | Get-Member -MemberType Property
It is one of PowerShell’s most important learning and discovery tools.
Handling null values is essential for writing safe scripts.
if ($value -eq $null) { "Value is null" }
Null coalescing operator (PowerShell 7+)
$result = $value ?? "Default Value"
Avoid null reference errors
$value?.Property
Set default if empty or null
if ([string]::IsNullOrEmpty($value)) { $value = "Default" }
Filter null results
Filter null resultsUse try/catch for null operations
try { $value.Property } catch { "Error due to null" }
Null handling prevents runtime errors and improves script reliability.
DSC is a configuration management platform in PowerShell used to define and maintain the desired state of systems.
Instead of writing scripts that describe how to configure a system, DSC describes what the final state should be.
Configuration WebConfig {
Node "Server01" {
WindowsFeature IIS {
Name = "Web-Server"
Ensure = "Present"
}
}
}
WebConfig
Start-DscConfiguration WebConfig -Wait -Verbose
DSC is widely used by DevOps, administrators, and configuration engineers.
DSC resources are the building blocks that define how DSC enforces configuration.
File → manage files/foldersService → manage Windows servicesPackage → install softwareRegistry → manage registry keysWindowsFeature → install server rolesA DSC resource typically includes:
Admins can create their own resources for:
DSC resources provide the actual automation logic behind the declarative configuration model.
PowerShell DSC supports two primary modes for delivering configuration to target nodes:
In push mode, the administrator manually sends the DSC configuration to a target node.
Command:
Start-DscConfiguration -Path "C:\MyDSC" -ComputerName Server01 -Wait -Verbose
In pull mode, nodes retrieve configuration from a DSC Pull Server when:
FeaturePush ModePull ModeDeploymentManualAutomatedScaleSmallLarge enterpriseInfrastructureNone requiredPull server neededDrift correctionNoYesBest forLabs, testingProduction, large fleets
Pull mode is the foundation of enterprise configuration management.
CIM cmdlets allow communication with remote systems using WS-Management (WinRM) instead of the older DCOM protocol used by WMI.
Get-CimInstanceNew-CimSessionInvoke-CimMethodSet-CimInstanceRemove-CimInstanceGet-CimInstance -ClassName Win32_OperatingSystem
Create a remote CIM session
$session = New-CimSession -ComputerName "Server01"
Use it:
Get-CimInstance -CimSession $session -ClassName Win32_Service
Invoke a CIM method
Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine="notepad.exe"}
CIM is the modern approach for system-level management in PowerShell.
WMI and CIM both describe system management information, but they differ in technology and standards.
Get-WmiObjectFeatureWMICIMProtocolDCOMWS-ManCross-platformNoYesPerformanceSlowerFasterSecurityOlder, less secureModern, encryptedPowerShell cmdletsLegacyRecommended
PowerShell provides multiple methods for object comparison.
Compares two sets of objects.
Example:
Compare-Object -ReferenceObject $old -DifferenceObject $new
Output includes:
$a -eq $b
$a -ne $b
$a -gt $b
$a -lt $b
Works on:
$set1 = 1,2,3
$set2 = 1,2,4
Compare-Object $set1 $set2
4. Compare object properties
$process1.Name -eq $process2.Name
5. Advanced comparison using Sort-Object -Unique
$items | Sort-Object -Unique
Object comparison in PowerShell is rich and supports structured data deeply.
A PSDrive is a PowerShell abstraction that allows accessing different data stores using a filesystem-like interface.
Examples of PSDrives:
PSDriveProviderPurposeC:FileSystemFiles and foldersHKLM:RegistryRegistry hiveEnv:EnvironmentEnvironment variablesCert:CertificatesCertificate storeFunction:Function providerFunctions in memoryVariable:Variable providerPowerShell variables
Get-PSDrive
Navigate like a file system
cd Env:
Get-ChildItem Env:
cd HKLM:\Software
Create a custom PSDrive
New-PSDrive -Name MyData -PSProvider FileSystem -Root "C:\Data"
PSDrives provide a unified navigation experience across data sources.
PowerShell modules allow reusability and distribution of functions, scripts, and cmdlets.
MyModule\
MyModule.psm1
MyModule.psd1 (optional manifest)
Step 2: Add functions to the .psm1
function Get-Hello {
"Hello World"
}
Step 3: Create a module manifest
New-ModuleManifest -Path "MyModule\MyModule.psd1" -RootModule "MyModule.psm1"
Step 4: Test the module
Import-Module .\MyModule
Get-Hello
Prerequisites:
Install-Module PowerShellGet
Register-PSRepository
Publish:
Publish-Module -Name MyModule -NuGetApiKey <YourAPIKey>
Step 6: Install module from Gallery
Install-Module MyModule
Modules are the backbone of scalable PowerShell development.
Get-Credential allows users to securely input credentials.
$cred = Get-Credential
Prompts a GUI window with:
Invoke-Command -ComputerName Server01 -Credential $cred -ScriptBlock { hostname }
$cred.Password | ConvertFrom-SecureString | Set-Content "password.txt"
Credentials should always be handled securely in automation scripts.
SecureString is a .NET type designed to store encrypted, in-memory strings, typically for passwords or sensitive data.
Read-Host "Enter password" -AsSecureString
Convert SecureString to plain text (not recommended)
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$text = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr)
SecureString improves security by ensuring sensitive data is protected.
PowerShell provides several methods to hide or suppress output.
Get-Process > $null
2. Use Out-Null
Get-Process | Out-Null
3. Assign output to a variable
$x = Get-Process
4. Use [void] cast
[void](Get-Process)
5. Use SilentlyContinue with error-producing commands
Remove-Item file.txt -ErrorAction SilentlyContinue
Output suppression is useful for clean scripts and automation.
Transcript logging records all activity in a PowerShell session, including:
This is extremely useful for:
Start-Transcript -Path "C:\Logs\session.log"
Stop a transcript
Stop-Transcript
Transcript logs support cybersecurity policies and traceability in enterprise environments.
PowerShell’s architecture consists of several tightly integrated layers, each responsible for translating user commands into executable .NET operations.
The core execution engine handles:
PowerShell dynamically resolves commands via:
Virtualize data stores as drives (FileSystem, Registry, Cert, Env, etc).
PowerShell is built on top of the .NET runtime:
Modules encapsulate:
PowerShell’s architecture is a hybrid of a shell, a dynamic language, and a .NET automation engine, making it extremely powerful and extensible.
PowerShell's pipeline is a streaming object pipeline, not a text pipeline like Bash.
Example:
Get-Process | Where-Object { $_.CPU -gt 20 }
This architecture allows PowerShell to scale from small scripts to enterprise automation pipelines.
PowerShell Remoting uses CLIXML (Command Line Interface XML) to serialize .NET objects.
Deserialized.<typename>.Example:
Get-Process -ComputerName Server01
Returns deserialized process objects (methods unavailable).
Deserialization guarantees secure, consistent remoting across environments.
PowerShell identifies and resolves commands using a specific ordered process.
ModuleName\Get-User
This system makes PowerShell flexible but sometimes confusing if aliases or functions shadow cmdlets.
PowerShell resolves commands using a strict hierarchy:
ls = alias for Get-ChildItemIf a function is named Get-Process, it overrides the built-in cmdlet.
You can still call the real cmdlet using:
Get-Command Get-Process -CommandType Cmdlet
Or fully-qualified syntax:
Microsoft.PowerShell.Management\Get-Process
This order provides flexibility and extensibility but requires careful naming in modules.
PowerShell script execution pipeline:
PowerShell caches compiled script blocks for reuse:
$sb = { param($x) $x + 10 }
Internally:
This dynamic compilation is what gives PowerShell high performance despite being a scripting language.
AST is a hierarchical representation of PowerShell code created during parsing.
For this script:
Get-Process | Where-Object { $_.CPU -gt 10 }
PowerShell creates an AST tree with nodes like:
AST nodes are immutable and represent the entire script structure.
AST-based analysis allows deep inspection of PowerShell scripts.
$ast = [System.Management.Automation.Language.Parser]::ParseFile("script.ps1", [ref]$null, [ref]$null)
Find all command names
$ast.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $true)
Find all variable references
$ast.FindAll({ $_ -is [System.Management.Automation.Language.VariableExpressionAst] }, $true)
AST analysis is crucial for writing secure, scalable PowerShell tooling.
A runspace pool is a collection of pre-created runspaces (PowerShell execution environments) that can be reused for high-performance parallel operations.
$pool = [runspacefactory]::CreateRunspacePool(1, 10)
$pool.Open()
Now each job can use a runspace from the pool.
Runspace pools are a foundational concept for building high-performance automation frameworks.
Runspaces allow high-performance multithreading by running multiple pipelines in parallel.
$pool = [runspacefactory]::CreateRunspacePool(1, 10)
$pool.Open()
2. Create PowerShell instance
$ps = [powershell]::Create()
$ps.RunspacePool = $pool
3. Add the script block
$ps.AddScript({ param($n) "Processing $n"; Start-Sleep 1 })
4. Add arguments
$ps.AddArgument(5)
5. Begin async execution
$handle = $ps.BeginInvoke()
6. Collect results
$result = $ps.EndInvoke($handle)
Runspaces give PowerShell performance comparable to C# async/parallel programming while keeping scriptability.