PowerShell Functions & Modules
Functions allow you to encapsulate reusable code, while modules help organize and share your PowerShell components.
Basic Functions
# Simple function
function Get-Greeting {
"Hello, PowerShell!"
}
# Calling the function
Get-Greeting
# Function with parameters
function Get-PersonalizedGreeting {
param(
[string]$Name,
[int]$Age
)
"Hello $Name, you are $Age years old!"
}
Get-PersonalizedGreeting -Name "Alice" -Age 30
Advanced Functions
function Get-SystemInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ComputerName,
[ValidateSet("CPU","Memory","Disk")]
[string]$Component = "CPU",
[switch]$Detailed
)
begin {
Write-Verbose "Starting system info collection for $ComputerName"
}
process {
switch ($Component) {
"CPU" {
$info = Get-CimInstance Win32_Processor -ComputerName $ComputerName
if ($Detailed) {
$info | Select-Object Name, NumberOfCores, MaxClockSpeed
} else {
$info | Select-Object Name, LoadPercentage
}
}
"Memory" {
Get-CimInstance Win32_PhysicalMemory -ComputerName $ComputerName |
Measure-Object -Property Capacity -Sum |
Select-Object @{Name="TotalGB";Expression={[math]::Round($_.Sum/1GB,2)}}
}
"Disk" {
Get-CimInstance Win32_LogicalDisk -ComputerName $ComputerName -Filter "DriveType=3" |
Select-Object DeviceID, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,2)}},
@{Name="FreeGB";Expression={[math]::Round($_.FreeSpace/1GB,2)}}
}
}
}
end {
Write-Verbose "Completed system info collection"
}
}
# Using the advanced function
Get-SystemInfo -ComputerName "localhost" -Component Memory -Detailed
Get-SystemInfo -ComputerName "localhost" -Component Disk -Verbose
Parameter Attributes
Attribute | Description | Example |
---|---|---|
[Parameter()] | Defines parameter behavior | [Parameter(Mandatory=$true)] |
[ValidateSet()] | Restricts to specific values | [ValidateSet("Low","Medium","High")] |
[ValidateRange()] | Restricts numeric range | [ValidateRange(1,100)] |
[ValidatePattern()] | Regex validation | [ValidatePattern("^[A-Z][a-z]+$")] |
[ValidateScript()] | Custom validation script | [ValidateScript({Test-Path $_})] |
[Alias()] | Alternative parameter names | [Alias("Server")] |
Pipeline Input
function Process-Files {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
[System.IO.FileInfo]$File
)
process {
[PSCustomObject]@{
Name = $File.Name
SizeKB = [math]::Round($File.Length/1KB,2)
LastModified = $File.LastWriteTime
}
}
}
# Using pipeline input
Get-ChildItem -File | Process-Files | Sort-Object SizeKB -Descending
Error Handling in Functions
function Get-FileContent {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Path
)
if (-not (Test-Path $Path)) {
Write-Error "File not found: $Path"
return
}
try {
Get-Content -Path $Path -ErrorAction Stop
}
catch {
Write-Error "Failed to read file: $_"
}
}
Get-FileContent -Path "C:\nonexistent.txt"
Creating Modules
Module Structure
# Directory structure
# MyModule/
# MyModule.psd1 # Module manifest
# MyModule.psm1 # Root module file
# Public/
# Get-SystemInfo.ps1
# Set-Configuration.ps1
# Private/
# HelperFunctions.ps1
Module Manifest (psd1)
@{
ModuleVersion = '1.0'
GUID = 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8'
Author = 'Your Name'
Description = 'My PowerShell module'
PowerShellVersion = '5.1'
RootModule = 'MyModule.psm1'
FunctionsToExport = @('Get-SystemInfo','Set-Configuration')
PrivateData = @{
PSData = @{
Tags = @('System','Configuration')
LicenseUri = 'https://opensource.org/licenses/MIT'
ProjectUri = 'https://github.com/you/MyModule'
}
}
}
Root Module (psm1)
# Export module members
$publicFunctions = @(Get-ChildItem -Path "$PSScriptRoot\Public\*.ps1")
$privateFunctions = @(Get-ChildItem -Path "$PSScriptRoot\Private\*.ps1")
# Dot source all functions
foreach ($file in @($publicFunctions + $privateFunctions)) {
try {
. $file.FullName
}
catch {
Write-Error "Failed to import function $($file.Name): $_"
}
}
# Export only the public functions
Export-ModuleMember -Function $publicFunctions.BaseName
Module Management
# Import a module
Import-Module MyModule -Force
# List loaded modules
Get-Module
# Remove a module
Remove-Module MyModule
# Install from PowerShell Gallery
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -Force
# Update a module
Update-Module -Name PSScriptAnalyzer