100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Your First PowerShell Script

Write, save, and run a real .ps1 script with parameters, control flow, and functions, and understand execution policy before you run it.

FoundationsBeginner8 min readJul 10, 2026
Analogies

Your First PowerShell Script

A PowerShell script is simply a plain text file saved with a .ps1 extension containing the same cmdlets and syntax you'd type interactively at the console. You run it by typing its path preceded by ./ (or .\ on Windows), such as ./backup.ps1, rather than just typing the filename - PowerShell requires this explicit path reference as a security measure so scripts in the current directory aren't accidentally executed.

🏏

Cricket analogy: Typing commands interactively at the console is like a batter playing improvised shots in the nets, while saving them into a .ps1 file and running it with ./script.ps1 is like a fielding drill sequence written into the coaching manual, run identically before every training session.

Execution Policy

By default, PowerShell's execution policy on Windows is Restricted, which blocks all scripts from running, including your own - only interactive commands work. This exists because scripts are a common malware delivery vector; running Set-ExecutionPolicy RemoteSigned -Scope CurrentUser lets locally authored scripts run freely while still requiring a valid digital signature on any script flagged by Windows as downloaded from the internet.

🏏

Cricket analogy: PowerShell's default execution policy blocking unsigned scripts is like a stadium's security gate refusing entry to anyone without an accredited pass - Set-ExecutionPolicy RemoteSigned is like the ground relaxing the rule to admit locally-issued passes while still checking any pass brought in from outside.

Never set Set-ExecutionPolicy Unrestricted or Bypass system-wide, and never run a downloaded script you haven't read just to make an error go away. Unrestricted allows any script, signed or not, from any source, to run silently - it's a common recommendation in outdated tutorials but a real security risk on any machine handling sensitive data.

Parameters, Control Flow, and Functions

A param() block at the top of a script (or function) declares the inputs it accepts, e.g. param([string]$Path, [int]$MaxCount = 10), letting you call it as ./script.ps1 -Path C:\Logs -MaxCount 5. Standard control flow includes if/elseif/else for branching and foreach ($item in $collection) { } for iterating, both using the same curly-brace block syntax as every other language construct in PowerShell.

🏏

Cricket analogy: A param() block defining function Set-Score { param($Runs, $Wickets) } is like a scorer's form with fixed fields to fill in before the innings starts, while a foreach loop stepping through every over mirrors reviewing each delivery of a completed innings one by one.

Writing a Reusable Function

The function keyword defines a named, reusable block of code with its own param() block, called just like a built-in cmdlet: function Get-StrikeRate { param($Runs, $Balls); return ($Runs / $Balls) * 100 } is invoked as Get-StrikeRate -Runs 120 -Balls 80. Functions can return values implicitly (any unassigned output in the function body is emitted) or explicitly with the return keyword, and defining functions inside a script keeps repeated logic in one place instead of duplicated across the file.

🏏

Cricket analogy: Writing function Get-StrikeRate { param($Runs,$Balls); return ($Runs/$Balls)*100 } once and calling it for every batter is like a statistician building one formula sheet used to calculate every player's strike rate instead of recalculating the math by hand for each name.

Comment-based help lets your own functions respond to Get-Help just like built-in cmdlets. Add a block comment starting with <# .SYNOPSIS ... .PARAMETER Runs ... .EXAMPLE ... #> immediately above (or inside) the function definition, and Get-Help Get-StrikeRate -Full will render it correctly.

powershell
<#
.SYNOPSIS
    Calculates a batting strike rate.
#>
function Get-StrikeRate {
    param(
        [Parameter(Mandatory)][int]$Runs,
        [Parameter(Mandatory)][int]$Balls
    )
    return [math]::Round(($Runs / $Balls) * 100, 2)
}

# --- main script body ---
param(
    [string]$PlayerName = 'Unknown',
    [int]$Runs = 0,
    [int]$Balls = 1
)

if ($Balls -le 0) {
    Write-Warning "Balls faced must be greater than zero."
} else {
    $rate = Get-StrikeRate -Runs $Runs -Balls $Balls
    Write-Output "$PlayerName's strike rate: $rate"
}

# Run it with: ./strike-rate.ps1 -PlayerName 'Root' -Runs 120 -Balls 80
  • A .ps1 file is a plain text script run with an explicit path, e.g. ./script.ps1.
  • The default execution policy (Restricted) blocks all scripts as a security measure.
  • Set-ExecutionPolicy RemoteSigned trusts local scripts while requiring signatures on downloaded ones.
  • Never use Unrestricted or Bypass execution policy system-wide.
  • A param() block at the top of a script or function declares its named inputs.
  • if/elseif/else and foreach provide standard branching and iteration.
  • The function keyword defines reusable, callable blocks of logic with their own param() block.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#PowerShellStudyNotes#YourFirstPowerShellScript#PowerShell#Script#Execution#Policy#StudyNotes#SkillVeris#ExamPrep