Ferramentas práticas para administradores de sistemas, redes, segurança e operações.

SYS-C0104 · Windows Server & PowerShell

PowerShell Scripting Basics

Write PowerShell that passes objects, supports -WhatIf, and does not treat execution policy as a boundary.

Updated 25 October 2026 · Pillar guide

This is an original planning guide. It is not a vendor manual, an official standard, or legal advice. Example addresses use documentation ranges. Review every command before you paste it.

Commands return objects, and policy is not a lock

PowerShell commands are verb-noun. Get-Help Verb-Noun -Examples is the page you read before you invent a flag. Get-Command finds what is installed. A script that assumes a module is present should say which module, and the host should have it installed on purpose, not imported from a random path.

Output is objects. The columns you see are a view. The next command can take the object. Text parsing is what you do when you have left PowerShell. Select-Object, Where-Object, and ForEach-Object are the ordinary tools. A long one-liner you cannot read on Monday is a script with names.

Execution policy controls whether a local script is allowed to start. It is not an access-control boundary. A person who can run powershell can bypass a policy. Do not describe the policy as the thing that keeps a server safe. The thing that keeps a server safe is who can log on, what the script does, and the account it runs as. Sign scripts if your organisation already does. Do not invent a signing ceremony in the middle of an outage.

-WhatIf and -Confirm are how you see a change before it happens, on cmdlets that support them. A script that changes users, services, or files should show the same preview. If a cmdlet has no -WhatIf, the script writes the plan and waits. The template generator drafts a skeleton. You delete every sample that is not this task.

A lab query, then a change you preview

The lab starts with a query that cannot change anything: a Get- command whose output you understand, filtered to one name you planted. You keep the output. The command builder on this site can draft that Get- line. Compare it to Get-Help before you run it on a server.

The change, when there is one, is a Set- or a New- against that same one name, with -WhatIf first. The WhatIf text should name the object you planted and no other. If it names a second object, the filter is wrong and you do not remove -WhatIf.

The script file lives in a path the operator account can read, and it is not world-writable in the Windows sense that every user can edit it. The account that runs it is named in the ticket. A scheduled task that runs as a domain admin because that was convenient is the mistake the Windows roles guide is trying to stop.

Errors stop the script. $ErrorActionPreference = 'Stop' is a choice you can explain, similar to a shell that exits on failure. A script that prints an error and continues through a loop of accounts will half-finish a change. Prefer a loop of one account until the one account is boring.

A change you can finish

Query in this window. Change one named object with -WhatIf, then without it, then Get- the object again and keep both outputs. A loop over a whole OU is a later window, after the one object was right.

Rollback is the previous value you recorded from the first Get-. If you did not record it, you are not ready to Set-.

  1. Get-Help the cmdlet and read the examples.
  2. Run a Get- that matches one planted object.
  3. Record the current values you might change.
  4. Run the change with -WhatIf and read every name it prints.
  5. Run it for real only if the names match the ticket.
  6. Get- the object again and keep the after line.
  7. Put the script where the run account can read it and others cannot edit it.

Mistakes that outlive the command

PowerShell fails in the same few ways. Each one looks finished on the day you type it. The list is here so the ticket can forbid them before the window, not so you can recognise them in an incident review.

Decisions to write down before the window

Decision 1 for PowerShell. The cmdlet is the one Get-Help described. The module name is in the ticket. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 2 for PowerShell. The first run is a Get- of one object. The output is saved. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 3 for PowerShell. A change supports a preview, or the script prints the plan and you approve that plan. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 4 for PowerShell. -WhatIf output names only the objects in the ticket. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 5 for PowerShell. The run account is named and is not a domain admin unless the cmdlet cannot work otherwise. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 6 for PowerShell. Execution policy is set the way the organisation already requires. It is not described as a boundary. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 7 for PowerShell. Errors stop the script. A loop over many objects waits until one object is done. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 8 for PowerShell. The previous value is the rollback. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 9 for PowerShell. The template was trimmed. Sample users from the generator are gone. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 10 for PowerShell. The script path is not editable by every user who can log on. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

Decision 11 for PowerShell. A second person read the filter aloud before -WhatIf was removed. Write that decision in the ticket before you change the host. The proof is the smallest command or screen that confirms it, recorded with the hostname and the time. If the host disagrees, the ticket changes. A second change does not go on top of a failed check. The rollback is the previous value you wrote down, not a reboot that hides which line mattered.

PowerShell checks before a change runs without -WhatIf

Check 1 in PowerShell checks before a change runs without -WhatIf. Get-Help was read for this cmdlet. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 2 in PowerShell checks before a change runs without -WhatIf. A one-object Get- output is in the ticket. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 3 in PowerShell checks before a change runs without -WhatIf. The previous value is written down. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 4 in PowerShell checks before a change runs without -WhatIf. -WhatIf names only the intended object. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 5 in PowerShell checks before a change runs without -WhatIf. The run account is the account in the ticket. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 6 in PowerShell checks before a change runs without -WhatIf. The script stops on errors. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 7 in PowerShell checks before a change runs without -WhatIf. No downloaded module was imported as part of this change. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 8 in PowerShell checks before a change runs without -WhatIf. Execution policy is not the control you are relying on. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 9 in PowerShell checks before a change runs without -WhatIf. The generator sample names are gone. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 10 in PowerShell checks before a change runs without -WhatIf. The after Get- matches the intended value. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 11 in PowerShell checks before a change runs without -WhatIf. Rollback is the previous value, and you know the Set- that puts it back. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 12 in PowerShell checks before a change runs without -WhatIf. A second person heard the filter. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 13 in PowerShell checks before a change runs without -WhatIf. The scheduled task, if any, uses the same script path you tested. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 14 in PowerShell checks before a change runs without -WhatIf. The hostname in the prompt matches the hostname in the ticket for PowerShell. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 15 in PowerShell checks before a change runs without -WhatIf. The result line includes the time and the person, not only the command. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 16 in PowerShell checks before a change runs without -WhatIf. You can point at the rollback value without searching a chat history. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Check 17 in PowerShell checks before a change runs without -WhatIf. Done is a sentence a second person can repeat: the proof for PowerShell happened, and the next host is not started early. Record the device name, the result, and the time on the same line. If the result does not match this check, stop and fix the ticket before you add another change. The rollback for this check is the previous value you wrote down, not a reboot. A reboot hides whether the check was the one that mattered. When the check passes, move to the next one. When it fails, the incident is this check.

Tools for this guide

These tools run in the browser on this site. They do not log into your machines.

Guides in this cluster

These supporting pages belong to this pillar. A published page is linked. The others are named until they are published.