PowerShell Command Basics — The Operations to Learn First and How to Use Them Safely
· Go Komura · PowerShell, Windows, Command Line, Automation, Legacy Asset Reuse
1. What to Grasp First
PowerShell is a command environment you can use for checking Windows settings, organizing files, investigating logs, processing CSVs, operating services, and automating routine work.
That said, there is no need to write complex scripts from day one. Just learn the following flow first, and you will already be quite effective in real work.
Find -> Look -> Filter -> Sort -> Output -> Change only if needed
The fundamentals of PowerShell are not about “memorizing long commands.” What matters are these three things:
- Being able to look up commands with
Get-CommandandGet-Help - Being able to pass results to the next command with the
|pipeline - Checking the impact with
-WhatIfand-Confirmbefore deleting, stopping, or changing anything
PowerShell lets you run “investigation” and “changes” on the same screen. That is convenient, but deletions and stops execute just as instantly, so the habit of starting from read-only checks is essential.
The code that appears in this article is published on GitHub as a complete sample set, including a collection of theme-by-theme scripts following the chapter structure (organized so you can practice safely in a workspace created in a temporary folder) and Pester tests.
powershell-command-basics - komurasoft-blog-samples (GitHub)
2. The Difference Between PowerShell and the Command Prompt
PowerShell looks similar to the traditional Command Prompt (cmd.exe), but the underlying philosophy is different.
| Aspect | Command Prompt | PowerShell |
|---|---|---|
| Primary output | Strings | Objects |
| Command names | dir, copy, etc. |
Get-ChildItem, Copy-Item, etc. |
| Processing results | Mainly string manipulation | Filtering and sorting using properties |
| Automation | Batch files | .ps1 scripts |
| Strengths | Compatibility with legacy command assets | Windows administration, CSV, JSON, APIs, routine work |
For example, when listing files, in cmd.exe you mostly look at the output of dir as a wall of text. In PowerShell, files are treated as objects with properties like Name, Length, and LastWriteTime.
Get-ChildItem
Once you understand this difference, operations like “show only files modified within the last 7 days, newest first” come naturally.
Get-ChildItem -File |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, Length, LastWriteTime
3. Windows PowerShell 5.1 and PowerShell 7.x
Windows ships with the long-standing Windows PowerShell 5.1 and the newer line, PowerShell 7.x.
In practice, this framing makes things clear.
| Variant | Executable | Main use |
|---|---|---|
| Windows PowerShell 5.1 | powershell.exe |
Legacy Windows-only modules, existing scripts, maintaining internal assets |
| PowerShell 7.x | pwsh.exe |
New scripts, cross-platform, ongoing feature improvements |
If you are learning fresh, basing yourself on PowerShell 7.x is fine. However, old internal admin scripts and Windows-specific modules are sometimes built assuming Windows PowerShell 5.1.
So in practice, the first thing to do is check the version.
$PSVersionTable
For a script that should run only on a certain version or later, writing the condition at the top reduces accidents.
#Requires -Version 7.0
4. Cmdlet Names Follow Verb-Noun
PowerShell’s standard commands basically take the Verb-Noun form.
Get-Process
Get-Service
Get-ChildItem
Copy-Item
Remove-Item
Export-Csv
Once you internalize this form, even unfamiliar commands become easier to find.
| Verb | Meaning | Example |
|---|---|---|
Get |
Retrieve | Get-Process |
Set |
Configure | Set-Location |
New |
Create | New-Item |
Copy |
Copy | Copy-Item |
Move |
Move | Move-Item |
Remove |
Delete | Remove-Item |
Start |
Start | Start-Service |
Stop |
Stop | Stop-Process |
Import |
Read in | Import-Csv |
Export |
Write out | Export-Csv |
Short names like dir, ls, cat, and cd also work, but most are aliases.
Get-Command dir
When keeping something as a script, using the full names rather than aliases is safer.
# Readable, but avoid in scripts
ls *.log
# Intent is clear
Get-ChildItem -Filter *.log
5. The Three Discovery Commands to Learn First
PowerShell has a great many commands, so learning “how to look things up” is more practical than memorization.
1. Get-Command — find available commands
Get-Command is the command for finding installed commands, functions, aliases, and applications.
# Find commands with the noun Process
Get-Command -Noun Process
# Find commands related to services
Get-Command *Service*
# Find commands related to CSV
Get-Command *Csv*
When you only half-remember a command name, use wildcards.
Get-Command *Item*
Get-Command *Content*
Get-Command *Json*
2. Get-Help — see how to use a command
Get-Help is the command for checking a command’s description, parameters, and examples.
Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Full
Get-Help Get-ChildItem -Online
At first, -Examples is the most useful.
Get-Help Where-Object -Examples
If the help is outdated or missing, update it from an elevated PowerShell session.
Update-Help
Depending on the environment, this requires internet connectivity and permissions. On corporate PCs, it can fail because of proxies or management policies.
3. Get-Member — look inside an object
PowerShell output is, in most cases, “objects” rather than “strings.” With Get-Member, you can check what properties and methods an object has.
Get-Process | Get-Member
Get-Service | Get-Member
Get-ChildItem | Get-Member
For example, services have properties such as Status and Name.
Get-Service | Select-Object Name, Status
Files have Name, Length, LastWriteTime, and so on.
Get-ChildItem -File | Select-Object Name, Length, LastWriteTime
When you “don’t know what to filter on,” check the property names with
Get-Memberfirst.
6. Pipeline Basics
PowerShell’s | passes the result of the command on the left to the command on the right.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
This example performs the following processing from left to right.
Get the process list
-> sort descending by CPU usage
-> show only the top 10
The frequently used combinations are these.
| Command | Role | Example |
|---|---|---|
Where-Object |
Filter by condition | Get only stopped services |
Sort-Object |
Sort | Order by most recently modified |
Select-Object |
Choose columns or counts | Show only name and size |
ForEach-Object |
Process each element | Process per file |
Export-Csv |
Output to CSV | Save investigation results |
Where-Object — filter by condition
# Show only stopped services
Get-Service | Where-Object { $_.Status -eq "Stopped" }
# Show only files larger than 100MB
Get-ChildItem -File |
Where-Object { $_.Length -gt 100MB }
# Show only files whose names contain backup
Get-ChildItem -File |
Where-Object { $_.Name -like "*backup*" }
$_ represents the current object flowing through the pipeline.
Where-Object { $_.Length -gt 100MB }
This evaluates “is the Length of the file currently being looked at greater than 100MB?”
From PowerShell 3.0 onward, a simplified syntax is also available.
Get-Service | Where-Object Status -EQ "Stopped"
While you are a beginner, however, the scriptblock syntax is easier to follow.
Get-Service | Where-Object { $_.Status -eq "Stopped" }
Sort-Object — sort
# Largest memory usage first
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
# Most recently modified first
Get-ChildItem -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 20 Name, LastWriteTime
Select-Object — choose only the columns you need
Get-Process |
Select-Object Name, Id, CPU, WorkingSet
It is also used to limit the count.
Get-Process | Select-Object -First 5
Get-Process | Select-Object -Last 5
Before writing to CSV, trimming down to just the needed columns with Select-Object makes the result easier to work with.
Get-Service |
Select-Object Name, DisplayName, Status, StartType |
Export-Csv .\services.csv -NoTypeInformation -Encoding UTF8
7. Use the Format Commands Last
PowerShell has commands for shaping the display.
Format-Table
Format-List
Format-Wide
These are for “on-screen display.” If you use them before outputting to CSV or before passing data to subsequent processing, you end up with display objects instead of the original properties.
# Avoid: display information leaks into the CSV
Get-Process |
Format-Table Name, CPU |
Export-Csv .\process.csv -NoTypeInformation
# Correct: select the properties first, then output CSV
Get-Process |
Select-Object Name, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
Remember
Format-*as “for showing on screen, at the very end,” and accidents go down.
8. File and Folder Operation Basics
What you use most in PowerShell is file and folder operations.
| What you want to do | Command |
|---|---|
| See the current location | Get-Location |
| Change location | Set-Location |
| See a listing | Get-ChildItem |
| Create a file or folder | New-Item |
| Copy | Copy-Item |
| Move | Move-Item |
| Rename | Rename-Item |
| Delete | Remove-Item |
| Check existence | Test-Path |
Check the current location
Get-Location
Move.
Set-Location C:\Work
If the path contains spaces, wrap it in quotes.
Set-Location "C:\Work Files\Reports"
See the file listing
Get-ChildItem
Get-ChildItem -File
Get-ChildItem -Directory
Get-ChildItem -Recurse
For filtering by extension, -Filter is handy.
Get-ChildItem -Filter *.log
To search subfolders too, use -Recurse.
Get-ChildItem C:\Logs -Filter *.log -Recurse
In locations with huge numbers of files, do not jump straight to -Recurse — narrow the target folder first and then run it.
Create
# Create a folder
New-Item -ItemType Directory -Path .\archive
# Create an empty file
New-Item -ItemType File -Path .\memo.txt
If the item may already exist, check first.
if (-not (Test-Path .\archive)) {
New-Item -ItemType Directory -Path .\archive
}
Copy
Copy-Item .\report.xlsx .\backup\report.xlsx
To copy an entire folder, use -Recurse.
Copy-Item .\data .\backup\data -Recurse
When overwriting might be involved, check the impact in advance.
Copy-Item .\data .\backup\data -Recurse -WhatIf
Move
Move-Item .\old.log .\archive\old.log
When moving multiple files by condition, attach -WhatIf first.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive -WhatIf
If everything looks right, remove -WhatIf.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive
Delete
Treat deletion with particular care.
Remove-Item .\old.log -WhatIf
Run it only after confirming the target is correct.
Remove-Item .\old.log
The combination of wildcards and -Recurse is powerful. Do not run it on a production folder right away — confirm via a listing first.
# First, confirm the targets
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Select-Object FullName, Length, LastWriteTime
# Next, confirm what would be deleted
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item -WhatIf
# Finally, execute
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item
9. Reading, Searching, and Writing Text Files
In log investigation, text file operations come up constantly.
Read a file
Get-Content .\app.log
To see only the tail end, use -Tail.
Get-Content .\app.log -Tail 50
To watch a log that keeps being appended to, use -Wait.
Get-Content .\app.log -Tail 20 -Wait
Search for strings
Select-String -Path .\app.log -Pattern "ERROR"
Multiple files can be targeted.
Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN"
You can also extract the file name, line number, and content from the search results into a CSV.
Select-String -Path .\logs\*.log -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8
Write to a file
"hello" | Set-Content .\memo.txt -Encoding UTF8
"next line" | Add-Content .\memo.txt -Encoding UTF8
For saving command results, Export-Csv or ConvertTo-Json is often easier to work with later than Out-File.
Get-Process |
Select-Object Name, Id, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
10. CSV Basics
CSV comes up constantly in business automation. In PowerShell, a CSV can be handled not as strings but as “objects with columns.”
Read a CSV
Suppose, for example, you have the following users.csv.
Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true
Read it in.
$users = Import-Csv .\users.csv
$users
The column names become properties.
$users | Select-Object Name, Department
Filter by condition
$users |
Where-Object { $_.Department -eq "Sales" }
CSV values often come in as strings, so be careful when dealing with true / false or numbers.
$users |
Where-Object { $_.Enabled -eq "true" }
Output to CSV
$users |
Where-Object { $_.Department -eq "Sales" } |
Export-Csv .\sales-users.csv -NoTypeInformation -Encoding UTF8
The iron rule is to never put Format-Table before Export-Csv.
# Avoid
$users | Format-Table | Export-Csv .\out.csv -NoTypeInformation
# Correct
$users | Select-Object Name, Department, Enabled | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
11. JSON Basics
JSON is also common in configuration files and Web APIs.
$data = Get-Content .\settings.json -Raw | ConvertFrom-Json
$data
Convert an object to JSON.
[pscustomobject]@{
Name = "BatchJob"
Enabled = $true
Retry = 3
} | ConvertTo-Json
When deep nesting is involved, specify -Depth.
$config | ConvertTo-Json -Depth 10 | Set-Content .\settings.json -Encoding UTF8
12. Process and Service Basics
View processes
Get-Process
Check the processes with the largest memory usage.
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
Filter by name.
Get-Process -Name notepad
Stop with care.
Stop-Process -Name notepad -WhatIf
If everything looks right, execute.
Stop-Process -Name notepad
View services
Get-Service
To see only stopped services:
Get-Service |
Where-Object { $_.Status -eq "Stopped" }
Filter by name.
Get-Service -Name "Spooler"
When restarting, confirm the target first as well.
Get-Service -Name "Spooler"
Restart-Service -Name "Spooler" -WhatIf
Service operations easily affect production work, so in production environments confirm the runbook, the maintenance window, and the recovery procedure first.
13. Event Log Basics
Event logs are indispensable for Windows investigation.
Check recent errors.
Get-WinEvent -LogName System -MaxEvents 100 |
Where-Object { $_.LevelDisplayName -eq "Error" } |
Select-Object TimeCreated, ProviderName, Id, Message
View the most recent 50 entries from the Application log.
Get-WinEvent -LogName Application -MaxEvents 50 |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
To filter by time period:
$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = "System"
StartTime = $start
} |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Saving investigation results to CSV makes them easier to share later.
Get-WinEvent -LogName System -MaxEvents 500 |
Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
Export-Csv .\system-events.csv -NoTypeInformation -Encoding UTF8
14. Variables, Arrays, and Hashtables
You can get work done with short commands alone, but once things get a little longer, variables become handy.
Variables
$path = "C:\Logs"
Get-ChildItem $path
PowerShell variables start with $.
$today = Get-Date
$limit = (Get-Date).AddDays(-30)
Arrays
$extensions = @("*.log", "*.txt", "*.csv")
foreach ($ext in $extensions) {
Get-ChildItem C:\Work -Filter $ext
}
Hashtables
A hashtable is a set of key-value pairs.
$params = @{
Path = "C:\Logs"
Filter = "*.log"
Recurse = $true
}
Get-ChildItem @params
This @params style is called “splatting.” It makes things more readable as the number of parameters grows.
15. Shaping Results with PSCustomObject
When you want to summarize investigation results in tabular form, [pscustomobject] is convenient.
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
UserName = $env:USERNAME
CheckedAt = Get-Date
}
You can build multiple results and turn them into a CSV.
Get-ChildItem C:\Logs -Filter *.log |
ForEach-Object {
[pscustomobject]@{
Name = $_.Name
FullName = $_.FullName
SizeMB = [math]::Round($_.Length / 1MB, 2)
LastWriteTime = $_.LastWriteTime
}
} |
Export-Csv .\log-files.csv -NoTypeInformation -Encoding UTF8
16. Script File .ps1 Basics
Turn frequently used processing into .ps1 files.
As an example, let’s build a script that lists old logs.
# Find-OldLogs.ps1
param(
[string]$Path = "C:\Logs",
[int]$Days = 30,
[string]$OutputPath = ".\old-logs.csv"
)
$limit = (Get-Date).AddDays(-$Days)
Get-ChildItem -Path $Path -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit } |
Select-Object FullName, Length, LastWriteTime |
Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Example run:
.\Find-OldLogs.ps1 -Path C:\Logs -Days 60 -OutputPath .\old-logs.csv
Accepting arguments with param() makes it easy to change the conditions later.
17. Execution Policy Basics
When you try to run a .ps1, you may see an error like this.
... cannot be loaded because running scripts is disabled on this system...
In that case, check the current execution policy.
Get-ExecutionPolicy
Get-ExecutionPolicy -List
On a personal development machine, if all you want is to run locally created scripts, setting RemoteSigned at the current-user scope is the common choice.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
On corporate PCs, however, this may be controlled by Group Policy. Do not force a workaround — check with your administrators and operational rules.
Execution policy is a safety feature that controls the conditions under which PowerShell runs scripts. It is not, however, a complete security boundary. In organizations, it needs to be considered together with signing, AppLocker, Microsoft Defender, privilege management, and log auditing.
18. Error Handling Basics
PowerShell sometimes keeps going even when errors occur.
For important processing, use -ErrorAction Stop and try/catch.
try {
Copy-Item .\source.txt .\backup\source.txt -ErrorAction Stop
Write-Host "Copy succeeded"
}
catch {
Write-Error "Copy failed: $($_.Exception.Message)"
}
When processing multiple files, recording failures lets you trace them afterward.
$results = foreach ($file in Get-ChildItem .\input -File) {
try {
Copy-Item $file.FullName .\backup -ErrorAction Stop
[pscustomobject]@{
FileName = $file.Name
Status = "OK"
Message = ""
}
}
catch {
[pscustomobject]@{
FileName = $file.Name
Status = "NG"
Message = $_.Exception.Message
}
}
}
$results | Export-Csv .\copy-result.csv -NoTypeInformation -Encoding UTF8
19. The Safe Order for Running Change Commands
In PowerShell, the procedure for safely handling change commands — delete, move, stop — matters.
The basic order is this:
1. Look at the targets with Get-* commands
2. Filter with Where-Object
3. Review the target list with Select-Object
4. Record it with Export-Csv
5. Preview the planned changes with -WhatIf
6. Run for real
As an example, let’s delete .tmp files older than 30 days.
Step 1: Look at the targets
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse
Step 2: Filter by condition
$limit = (Get-Date).AddDays(-30)
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
Step 3: Show only the columns you need
$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
$targets |
Select-Object FullName, Length, LastWriteTime
Step 4: Keep an audit trail
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8
Step 5: Confirm with WhatIf
$targets | Remove-Item -WhatIf
Step 6: Execute
$targets | Remove-Item
Following this order reduces accidents of the “we don’t know what we deleted” variety.
20. A List of Frequently Used Basic Commands
Location and files
| Purpose | Example command |
|---|---|
| Show the current folder | Get-Location |
| Change folders | Set-Location C:\Work |
| Show a listing | Get-ChildItem |
| Show files only | Get-ChildItem -File |
| Show folders only | Get-ChildItem -Directory |
| Search subfolders too | Get-ChildItem -Recurse |
| Check existence | Test-Path .\file.txt |
| Create a folder | New-Item -ItemType Directory .\backup |
| Copy | Copy-Item .\a.txt .\backup\a.txt |
| Move | Move-Item .\a.txt .\archive\a.txt |
| Preview a deletion | Remove-Item .\a.txt -WhatIf |
Object manipulation
| Purpose | Example command |
|---|---|
| Filter by condition | Where-Object { $_.Status -eq "Running" } |
| Sort | Sort-Object LastWriteTime -Descending |
| Choose columns | Select-Object Name, LastWriteTime |
| Show only the top entries | Select-Object -First 10 |
| Process each element | ForEach-Object { $_.Name } |
| Inspect the contents | Get-Member |
Input and output
| Purpose | Example command |
|---|---|
| Read text | Get-Content .\app.log |
| View the tail | Get-Content .\app.log -Tail 50 |
| Search strings | Select-String -Path .\app.log -Pattern "ERROR" |
| Read a CSV | Import-Csv .\users.csv |
| Write a CSV | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8 |
| Read JSON | Get-Content .\a.json -Raw | ConvertFrom-Json |
| Write JSON | $obj | ConvertTo-Json -Depth 10 |
Windows investigation
| Purpose | Example command |
|---|---|
| Process list | Get-Process |
| Service list | Get-Service |
| Event logs | Get-WinEvent -LogName System -MaxEvents 100 |
| Environment variables | Get-ChildItem Env: |
| PowerShell version | $PSVersionTable |
| Execution policy | Get-ExecutionPolicy -List |
21. Practical Sample: Investigate Logs and Build a Report
Consider a requirement like this:
From the .log files under C:\App\Logs, find lines containing ERROR in files modified within the last 7 days, and compile them into a CSV.
Rather than writing the finished form straight away, build it in stages.
Step 1: Find the log files
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse
Step 2: Narrow to the last 7 days
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since }
Step 3: Search for ERROR
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR"
Step 4: Output to CSV
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-report.csv -NoTypeInformation -Encoding UTF8
Step 5: Turn it into a script
# Export-ErrorReport.ps1
param(
[string]$LogPath = "C:\App\Logs",
[int]$Days = 7,
[string]$Pattern = "ERROR",
[string]$OutputPath = ".\error-report.csv"
)
$since = (Get-Date).AddDays(-$Days)
Get-ChildItem $LogPath -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern $Pattern |
Select-Object Path, LineNumber, Line |
Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Example run:
.\Export-ErrorReport.ps1 -LogPath C:\App\Logs -Days 14 -Pattern "ERROR|FATAL" -OutputPath .\errors.csv
22. Practical Sample: Archive Old Files
Next is an example that moves rather than deletes.
Of the files in C:\Work\Reports, move the .xlsx files not modified in 90 days or more to C:\Work\Archive.
Confirm the targets
$source = "C:\Work\Reports"
$dest = "C:\Work\Archive"
$limit = (Get-Date).AddDays(-90)
$targets = Get-ChildItem $source -Filter *.xlsx -File |
Where-Object { $_.LastWriteTime -lt $limit }
$targets | Select-Object FullName, Length, LastWriteTime
Create the archive destination
if (-not (Test-Path $dest)) {
New-Item -ItemType Directory -Path $dest
}
Output an audit trail
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\archive-targets.csv -NoTypeInformation -Encoding UTF8
Confirm with WhatIf
$targets | Move-Item -Destination $dest -WhatIf
Execute
$targets | Move-Item -Destination $dest
If file name collisions are possible, this will fail as is. In practice, decide rules in advance: split into year-month folders, append a timestamp to the destination file name, or skip when a file already exists.
23. Common Stumbling Blocks
| Symptom | Cause | Remedy |
|---|---|---|
| Commands are too long to remember | Trying to memorize | Look them up with Get-Command and Get-Help -Examples |
$_ makes no sense |
Insufficient understanding of the pipeline’s current value | Learn it via the form Where-Object { $_.Name -like "*log*" } |
| The CSV comes out strange | Running Export-Csv after Format-Table |
Run Export-Csv after Select-Object |
| Paths with spaces fail | Missing quotes | Wrap them like "C:\Work Files\a.txt" |
| Scripts won’t run | Execution policy | Check with Get-ExecutionPolicy -List |
| Too many deletion targets | Conditions are too broad | Confirm first with Select-Object FullName and -WhatIf |
| Can’t figure out property names | Not looking at the object structure | Use Get-Member |
| Garbled characters | Mismatched encoding assumptions | Check the -Encoding of input/output and the consuming application |
24. The Order to Learn Commands In
There is no need to learn every command from the start.
We recommend this order.
Stage 1: Look and find
Get-Command
Get-Help
Get-Member
Get-Location
Set-Location
Get-ChildItem
Get-Content
Select-String
Stage 2: Filter and shape
Where-Object
Sort-Object
Select-Object
ForEach-Object
Format-Table
Format-List
Stage 3: Input and output
Import-Csv
Export-Csv
ConvertFrom-Json
ConvertTo-Json
Set-Content
Add-Content
Out-File
Stage 4: Change
New-Item
Copy-Item
Move-Item
Rename-Item
Remove-Item
Start-Service
Stop-Service
Restart-Service
Stop-Process
Always learn the change commands paired with the corresponding verification commands.
# Look
Get-ChildItem .\logs -Filter *.tmp
# See what would be deleted
Get-ChildItem .\logs -Filter *.tmp | Remove-Item -WhatIf
# Execute
Get-ChildItem .\logs -Filter *.tmp | Remove-Item
25. An Operational Checklist for the Field
When using PowerShell in business operations, checking the following points keeps things safe.
- Confirmed whether the PowerShell being run is
powershell.exeorpwsh.exe - Checked the version with
$PSVersionTable - Displayed the targets with
Get-*commands before making changes - Reviewed the
Where-Objectconditions on screen - Used
-WhatIfbefore deleting, moving, or stopping - Saved the pre-execution target list to CSV
- Confirmed backups or recovery procedures in production environments
- Checked the script execution policy and internal rules
- Prepared log output for error cases
- Used full command names rather than aliases in shared scripts
26. Conclusion
The fundamentals of PowerShell are not about memorizing a mountain of commands. What pays off in real work is internalizing this pattern:
Find with Get-Command
See usage with Get-Help
Check properties with Get-Member
Look at targets with Get-*
Filter with Where-Object
Shape columns with Select-Object
Keep a trail with Export-Csv
Preview changes with -WhatIf
Execute last
Above all, PowerShell is a powerful environment that can delete files, stop services, kill processes, and even manipulate the registry. Precisely for that reason, what you should learn first is not “the dangerous commands” but “the procedure for safely confirming your targets.”
Look -> Filter -> Record -> Rehearse -> Execute
Stick to this order, and PowerShell stops being just a black screen and becomes a practical tool for organizing, investigating, and automating Windows work.
Reference Links
- The complete sample code for this article (theme-by-theme scripts and Pester tests) - komurasoft-blog-samples (GitHub)
- PowerShell Documentation - Microsoft Learn
- Installing PowerShell 7 on Windows - Microsoft Learn
- Differences between Windows PowerShell 5.1 and PowerShell 7.x - Microsoft Learn
- Get-Command - Microsoft Learn
- Get-Help - Microsoft Learn
- Get-Member - Microsoft Learn
- about_Pipelines - Microsoft Learn
- Where-Object - Microsoft Learn
- Select-Object - Microsoft Learn
- Import-Csv - Microsoft Learn
- Export-Csv - Microsoft Learn
- about_Execution_Policies - Microsoft Learn
Related Articles
- Sorting Out Windows Character Encodings and Line Endings
- A Migration Guide for the VBScript Deprecation
- Pitfalls of COM/OCX/ActiveX Development
Services Related to This Topic
Windows Application Development
We support the development of Windows software such as business applications, equipment integration, and communication tools.
Legacy Asset Reuse and Migration Support
We support inventorying, refurbishing, and migrating existing assets including old batch files, VBScript, VBA, PowerShell, and COM / ActiveX.
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Practical PowerShell Command Recipes — Growing the Small Tools You Use Every Day
A practical roundup of PowerShell commands for everyday work, covering where to use Measure-Object, Group-Object, Select-String, Compare-...
How to Run PowerShell from C# (CSharp) and Receive the Results as Objects
How to launch PowerShell from C# and receive results as PSObject rather than strings — a practical walkthrough of the PowerShell SDK, Add...
Testing PowerShell with Pester — A Practical Approach to Making Operations Scripts Harder to Break
A practical walkthrough of testing PowerShell scripts with Pester v5 — safely covering date handling, file operations, deletion logic, mo...
Applied PowerShell Scripting — Safely Automating Log Investigation, Archiving, and Reporting
Practical steps for safely automating log investigation, CSV reporting, archiving old logs, keeping audit trails, and Task Scheduler exec...
Preparing for VBScript Deprecation: An Audit Guide for VBA and Internal Tools
Preparing for the phased deprecation of VBScript: inventorying VBA, Excel macros, and internal tools, static detection, execution logging...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
Where This Topic Connects
This article connects naturally to the following service pages.
Windows App Development
We support Windows desktop applications that involve resident processing, device integration, operational logging, and maintainable structure.
Author Profile
Profile page for the article author.
Go Komura
Representative of KomuraSoft LLC
Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.
Public links