Um momento
0xB0Lesson 12 of 17

Scripts and modules

Save code as .ps1 scripts with parameters, share functions by dot-sourcing and modules, and install modules from the gallery.

26 min 7-question quiz 2 code exercises
By the end of this lesson you can
  • Write and run .ps1 scripts with their own param() block, and understand execution policy
  • Reuse functions by dot-sourcing and by building a .psm1 module
  • Find and install modules from the PowerShell Gallery, and customize your $PROFILE

A script is a .ps1 file. Run it by path: .\Get-Report.ps1 (or ./Get-Report.ps1). The .\ matters - PowerShell never runs scripts from the current folder by bare name, so a malicious ls.ps1 can’t hijack ls.

A script can start with its own param() block, exactly like a function, and then takes parameters: .\Get-Report.ps1 -Enclosure volcano -Days 7. Inside, $PSScriptRoot is the folder the script lives in - use it to find files that sit next to the script.

scripts.ps1
1$folder = Join-Path ([IO.Path]::GetTempPath()) "scripts-$(Get-Random)"
2New-Item -ItemType Directory -Path $folder | Out-Null
3Set-Content -Path (Join-Path $folder 'Get-Welcome.ps1') -Value @'
4param(
5  [Parameter(Mandatory)][string]$Name,
6  [int]$Times = 1
7)
8foreach ($i in 1..$Times) { "Welcome, $Name!" }
9'@
10& (Join-Path $folder 'Get-Welcome.ps1') -Name 'Skyla' -Times 2
11$script = Join-Path $folder 'Get-Welcome.ps1'
12& $script 'Pebble'
Output
Welcome, Skyla!
Welcome, Skyla!
Welcome, Pebble!

The & is the call operator: it runs a command whose name or path is in a string or variable. You need it whenever the path is computed or contains spaces - & "C:\Dragon Tools\report.ps1".

Sharing functions: dot-sourcing and modules

Running a script normally gives it its own scope: when it ends, its variables and functions disappear. Two ways to keep them:

  • Dot-sourcing: . .\helpers.ps1 (a dot, a space, then the path) runs the file in your scope, so its functions stay defined. Quick, but everything it defines leaks in.
  • Modules: a .psm1 file of functions. Import-Module .\Dragons.psm1 loads it, and Export-ModuleMember chooses which functions are public - helpers stay private. Put a module folder in one of the paths in $env:PSModulePath and it even loads automatically the first time you call one of its commands.
module.ps1
1$folder = Join-Path ([IO.Path]::GetTempPath()) "module-$(Get-Random)"
2New-Item -ItemType Directory -Path $folder | Out-Null
3$modulePath = Join-Path $folder 'Dragons.psm1'
4Set-Content -Path $modulePath -Value @'
5function Get-Roar { param([string]$Name) "$Name says $(Get-RoarSound)" }
6function Get-RoarSound { 'RAAAWR' }
7Export-ModuleMember -Function Get-Roar
8'@
9Import-Module $modulePath
10Get-Roar -Name 'Ember'
11[bool](Get-Command Get-Roar -ErrorAction SilentlyContinue)
12[bool](Get-Command Get-RoarSound -ErrorAction SilentlyContinue)
13(Get-Module Dragons).ExportedFunctions.Keys -join ','
14Remove-Module Dragons
Output
Ember says RAAAWR
True
False
Get-Roar

The module’s public function can still call its private helper, but you can’t. That’s encapsulation.

Thousands of ready-made modules live on the PowerShell Gallery (powershellgallery.com): Find-Module *azure* searches it and Install-Module Pester -Scope CurrentUser installs one for just you. (PowerShell 7.4 adds the faster Install-PSResource.) Popular picks: Pester for testing, PSScriptAnalyzer for linting, Az for Azure and Microsoft.Graph for Microsoft 365.

Finally, your profile - the script at $PROFILE - runs every time PowerShell starts. It’s the place for your favorite aliases, functions and prompt tweaks. notepad $PROFILE (or code $PROFILE) opens it; create it first with New-Item -Force $PROFILE if it doesn’t exist.

Key takeaways

  • Run scripts by path (.\script.ps1); give them a param() block; use $PSScriptRoot for nearby files.

  • The call operator & runs a command or script whose path is in a variable.

  • Dot-source (. .\file.ps1) to load functions into your scope; build a .psm1 module to share them properly.

  • Install-Module gets modules from the PowerShell Gallery; $PROFILE customizes every session.

Lesson quiz

7 questions · pass with 5 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write PowerShell scripts

Write a script in the editor and run it for real against sample input, which is piped into your script as $input. Scripts run on PowerShell 6.2 through Try It Online (tio.run), a free public service, so these exercises avoid PowerShell 7-only syntax; your script and test input are sent there.

Exercise 1

A script with parameters

+25 XP

Finish the script file the starter writes, Get-Enclosure.ps1, so that it has a param() block with a mandatory -Name and a -Size that must be small, medium or large (default medium), and outputs Ember needs a medium enclosure.

Then, for each input line (Name or Name Size), call the script with the call operator &, passing -Size only when the line has one.

  • Three dragons
script.ps1
Loading editor…

Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.

Exercise 2

Build a module

+25 XP

Write a module Keepers.psm1 (the starter saves it to a temporary folder) containing two functions:

  • Get-ShiftKeeper -Hour <int> returns Ada for hours 6-13, Grace for 14-21 and Linus otherwise.
  • Test-DayShift - a private helper (not exported) that Get-ShiftKeeper may use.

Export only Get-ShiftKeeper. The provided code imports the module, looks up each input hour, and checks the helper is hidden.

  • Around the clock
script.ps1
Loading editor…

Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: