常见Powershell指令和DOS指令
信安大二上,正入门学习操作系统,老师让我们熟悉常规PowerShell指令和DOS指令,遂记录所学内容,做好知识管理第一步。
我让DeepSeek为我设计了几道题目, 便于我巩固知识点。
PowerShell常见指令
. Alias vs 真实命令
PowerShell 为了照顾 Linux 和 CMD 用户的习惯,内置了许多别名。但在写脚本时,强烈建议使用官方全称,以避免歧义并提高可读性。
| 常用别名 | 官方全称(推荐在脚本中使用) | 作用 |
|---|---|---|
pwd | Get-Location | 获取当前工作目录 |
cd | Set-Location | 切换目录 |
ls/dir | Get-ChildItem | 列出目录内容 |
echo | Write-Output | 输出文本或对象到管线 |
cat | Get-Content | 读取文件内容 |
cp | Copy-Item | 复制文件或目录 |
mv | Move-Item | 移动或重命名文件 |
rm | Remove-Item | 删除文件或目录 |
👉 学习技巧:在终端输入 Get-Alias ls,即可查看 ls 背后的真实命令。
输出与重定向符号:> 和 >>
>(覆盖写入):像推土机。执行时先清空目标文件原有的所有内容,再写入新内容。 >>(追加写入):像流水账。保留目标文件原有的内容,把新内容写到文件的最末尾。 .\ 是 PowerShell 中非常基础且极其重要的一个符号。它翻译过来就是:“当前目录下的”。. \ 的含义
.(点):代表当前目录(Current Directory)。 \(反斜杠):是 Windows 系统里的路径分隔符。所以,.\task1.ps1 的意思就是:“运行当前目录下的 task1.ps1 这个文件”。
注意区分:
Write-Host 只能把文本打印到终端屏幕,不能被重定向到文件;而 Write-Output(即 echo)会被送入管道,可以被 > 和 >> 写入文件。
3. 面向对象输出带来的“困扰”
PowerShell 经常会有大量输出。比如输入 Get-Date 或 Get-Location,终端会输出几百行类似 DisplayHint : DateTime、PSPath : Microsoft.PowerShell.Core\FileSystem::… 的属性列表。
原因:PowerShell 是基于 .NET 的面向对象语言,返回的是一个“对象”。 如何只提取关键信息? 使用点属性或格式化输出: powershell (Get-Location).Path # 只输出路径字符串 (Get-Date).ToString("yyyy-MM-dd") # 只输出日期字符串代码练习:
#1.pwdGet-Date#2.mkdir os_lab cd os_lab#3.dir#4.echo"Welcome to OS lecture"#5.echo'Hello World'>.\fqb.txt#6.echo'Hello'>.\fqb.txt#7.cat.\fqb.txt#8.cpfqb.txt fqb2.txt#9.mvfqb2.txt fqb3.txt#10.rmfqb3.txt#11.dir>.\filelist.txtdir>>.\filelist.txt踩坑记录
坑 1:VS Code 里的黄波浪警告
写 pwd 时,VS Code 提示:‘pwd’ is an alias of ‘Get-Location’. Alias can introduce possible problems and make scripts hard to maintain.
原因:VS Code 的 PowerShell 插件自带代码质检员(PSScriptAnalyzer),建议在脚本中避免使用别名。 解决:新建一个 PSScriptAnalyzerSettings.psd1 配置文件并在 VS Code 中配置路径,或者直接改成全称(推荐初学者直接用全称)。坑 2:套娃文件夹 (os_lab\os_lab\os_lab…)
运行脚本几次后,我发现路径变成了practice\os_lab\os_lab\os_lab...。
原因:脚本缺乏“幂等性”。每次运行都会无条件执行 mkdir os_lab 和 cd os_lab。如果不退出当前目录就再次运行,就会在现有文件夹里再建一个同名文件夹。 解决:在创建文件夹前加判断,并使用绝对路径: powershell $labPath = "C:\Users\你的用户名\Desktop\practice\os_lab" if (!(Test-Path $labPath)) { New-Item -ItemType Directory -Path $labPath } Set-Location $labPath#1.echo8 5 3 7|measure-object-Sum-Max-Min-Average#2.echo'Hello World'|Measure-Object-Property Length-Sum#3.$filePath="C:\Users\15808\Desktop\practice\filelist.txt"if(Test-Path$filePath){Get-Content$filePath|Measure-Object-Property Length-Average}else{Write-Warning"the filelist.txt can not be found."}#4.echo'Hello World'|Out-FileFilePath.\hello.txt#5.echo'Welcome to OS'|Out-FileFilePath.\hello.txt-Append#6.ls|sortWrite-Host"task2 is finished."本次任务最终跑通的命令涵盖了 PowerShell 最常用的几个核心模块。
1. 数据输出与管道
| 指令/符号 | 作用 | 示例 |
|---|---|---|
echo(Write-Output) | 将内容输出到屏幕或管道 | echo 8 5 3 7 |
|(管道) | 把前一个命令的输出,作为后一个命令的输入 | echo 8 5 3 7 | Measure-Object |
| 裸引号 | 直接输出字符串(PowerShell 特性,等价于 echo) | 'Hello World' | Out-File hello.txt |
2. 统计与测量
| 指令 | 作用 | 示例 |
|---|---|---|
Measure-Object | 测量对象的数值属性(体检员) | -Sum(和),-Maximum(最大),-Minimum(最小),-Average(平均),-Property Length(测量长度) |
3. 文件读写与目录管理
| 指令 | 作用 | 示例 |
|---|---|---|
Test-Path | 判断文件/文件夹是否存在(常用于容错) | if (Test-Path $FilePath) {...} |
Get-Content | 读取文件内容(按行拆成字符串对象) | Get-Content "filelist.txt" |
Out-File | 将输出写入文件 | -FilePath(指定路径),-Append(追加模式), 默认覆盖 |
ls(Get-ChildItem) | 列出当前目录内容 | ls -Exclude "*.txt" |
sort(Sort-Object) | 对输入对象进行排序 | ls | sort |
4. 辅助工具
| 指令 | 作用 |
|---|---|
cd ../cd 文件夹 | 切换当前工作目录 |
pwd | 查看当前终端的完整路径 |
Select-Object | 挑选对象的特定属性,常用-ExpandProperty提取纯字符串 |
Remove-Item | 删除文件或文件夹 |
#任务 3:变量与算术(对应文件第 5、6 节)#目标:掌握变量 $、单双引号、算术运算和数组。#要求:新建 task4.ps1,完成:#1.定义变量 $name="你的名字",$port=8081。$name="你的名字"$port=8081#2. 定义 $today="Thursday"。$today="Sunday"#3.分别用单引号和双引号输出 'Today is $today' 和 "Today is $today",观察区别。'Today is $today'"Today is$today"#4. 定义变量 $v1="the covid in guangzhou",赋值给 $v2,并输出 $v2。$v1="the covid in guangzhou"$v2=$v1$v2#5. 计算 6/2 和 6/25,观察整数和浮点数的区别。6/2 6/25#6. 定义 $x=2,$y=4。计算 $x+$y、$x*$y、$x/$y。$x= 2$y= 4$x+$y$x*$y$x/$y#7.定义一个数组 $v=1,2,3,输出它。$v=1,2,3,4$v一、 核心语法点总结表(查字典必备)
为了方便查阅,我将本次脚本涉及的语法点整理成了下表:
| 类别 | 语法点 / 符号 | 作用 | 代码示例 |
|---|---|---|---|
| 核心Cmdlet | Get-Process | 获取系统当前运行的所有进程对象。 | Get-Process |
| 核心Cmdlet | Stop-Process | 结束一个或多个进程。 | Stop-Process -Name notepad |
| 核心Cmdlet | Write-Host | 向控制台打印输出文本,常配合颜色参数美化终端。 | Write-Host "Hello" -ForegroundColor Green |
| 核心Cmdlet | Where-Object | 过滤命令,从管道传过来的集合中筛选符合条件的对象。 | ... | Where-Object { $_.Id -eq 123 } |
| 核心Cmdlet | Format-Table | 格式化输出,将对象以表格的形式展示指定属性。 | Get-Process | Format-Table Name, Id |
| 管道与对象 | |(管道符) | 将左边命令的输出结果(对象),作为右边命令的输入。 | Get-Process | Stop-Process |
| 管道与对象 | $_ | 当前对象,在Where-Object的脚本块{ }中代表当前处理的对象。 | Where-Object { $_.ProcessName ... } |
| 管道与对象 | .(点号) | 属性访问符,用于获取对象的某个属性值。 | $_.ProcessName(获取进程名) |
| 变量与运算符 | $ | 变量赋值符,用于将数据存入变量。 | $procs = Get-Process |
| 变量与运算符 | -like | 模糊匹配运算符,配合通配符*使用。 | $_.ProcessName -like "*notepad*" |
| 流程控制 | if...else | 条件分支语句,根据条件真假执行不同代码块。 | if ($procs) { ... } else { ... } |
| 参数与细节 | -Force | 强制参数,忽略系统确认提示直接执行。 | Stop-Process -Force |
| 参数与细节 | `n | 反引号+n,字符串中的换行转义字符。 | Write-Host "第一行`n第二行" |
| 参数与细节 | .\ | 执行当前目录脚本的路径前缀。 | .\task5.ps1 |
疑惑 :为什么在 VS Code 里执行会突然报错connect ETIMEDOUT?
问题重现:在 VS Code 运行脚本时,弹出错误窗口:connect ETIMEDOUT \\\\.\pipe\PSES_xxx,脚本无法继续运行。
原因排查:这不是脚本代码写错了!这是 VS Code 的 PowerShell 扩展进程与后台的 PowerShell 编辑器服务(PSES)之间的命名管道(Named Pipe)通信超时了。
#1.Get-Process#2,#3.$process=Get-Process|Where-Object{$_.ProcessName-like'*notepad*'}if($process){Write-Host"the notepad has been found."-ForegroundColor Green$process|Format-TableProcessName,Id,CPU-AutoSize$process|Stop-Process-Force}else{Write-Host"the notepad can not be found."}#目标:一次性掌握 if、switch、while、do until、for、foreach。#要求:新建 task5.ps1,把下面所有控制语句写在一个脚本里(用 Write-Host 打印提示词分隔不同结构):#1.if:定义一个变量 $score = 85。如果大于 90 输出 "A",如果大于 80 输出 "B",否则输出 "C"。(使用 -gt)。$sorce=85if($sorce-gt90){Write-Host"A"}elseif($socre-gt80){Write-Host"B"}else{Write-Host"C"}#2. switch:定义 $day = "Monday",用 switch 输出对应中文“星期一”。$day="Monday"switch($day){"Monday"{Write-Host"output xingqiyi"}default{Write-Host"output unknow"}}#3. while:用 while 循环输出 1 到 5。$i=1while($i-le5){Write-Host$i$i++}#4. do until:用 do until 循环输出 1 到 3(条件是大于 3 时停止)。$j=1do{Write-Host$j$j++}until($j-gt3)#5. for:用 for 循环倒计时输出 5 到 1。for($k=5;$k-ge1;$k--){Write-Host$k}#6. foreach:定义一个数组 $fruits = "Apple", "Banana", "Orange",用foreach遍历输出。$fruits="Apple","Banana","Orange"foreach($fruitin$fruits){Write-Host$fruit}📌 六大控制结构核心语法表
| 结构名称 | 语法格式 | 核心特点 | 适用场景 | 精简示例 |
|---|---|---|---|---|
| if / elseif / else | if (条件) { ... }elseif (条件) { ... }else { ... } | 互斥执行,一旦满足即跳出 | 条件分支判断 | if ($score -gt 90) { "A" } |
| switch | switch ($变量) {"匹配值" { ... }default { ... } } | 多值精确匹配(支持通配符/正则) | 多固定值判断 | switch ($day) { "Monday" { "星期一" } } |
| while | while (条件) { ... } | 先判断,后执行,可能一次都不执行 | 未知次数的循环 | while ($i -le 5) { $i++ } |
| do until | do { ... } until (条件) | 先执行,后判断,至少执行一次 | 必须执行一次的场景 | do { $j++ } until ($j -gt 3) |
| for | for (初始化; 条件; 迭代) { ... } | 计数循环,控制最灵活 | 已知循环次数/倒计时 | for ($k=5; $k -ge 1; $k--) { ... } |
| foreach | foreach ($元素 in $集合) { ... } | 自动遍历集合,无需索引 | 遍历数组/集合 | foreach ($f in $fruits) { ... } |
PowerShell 特有运算符对照表
PowerShell不使用>、<、==等符号,而是使用字母组合,这是写脚本时最容易踩坑的地方。
| 逻辑含义 | PowerShell 运算符 | 其他语言常见写法 | 示例 |
|---|---|---|---|
| 大于 | -gt(Greater Than) | > | $score -gt 90 |
| 大于等于 | -ge(Greater or Equal) | >= | $i -ge 1 |
| 小于 | -lt(Less Than) | < | $i -lt 5 |
| 小于等于 | -le(Less or Equal) | <= | $i -le 5 |
| 等于 | -eq(Equal) | == | $day -eq "Monday" |
| 不等于 | -ne(Not Equal) | != | $day -ne "Monday" |
functionGreet-User{param([string]$Name,[int]$Age)Write-Output"Hello$Name, you are$Ageyears old."}- 在函数内部,使用 param() 块来声明该函数可以接收哪些参数。注意:param() 块必须是函数体内的第一个语句。
- PowerShell 是弱类型语言,但为了代码的健壮性,强烈建议在 param() 块中为参数指定数据类型(如 [string]、[int]、[bool] 等)
- 在输出字符串时,使用双引号 " " 可以实现变量替换。
“Hello $Name”:PowerShell 会自动将 $Name 替换为变量实际的值。
(注意:如果使用单引号 ’ ',则不会进行变量替换,会原样输出 $Name)
- 用函数时,可以直接按顺序传递参数(位置参数),也可以指定参数名传递(命名参数,推荐写法,可读性更高)。
位置传参:Greet-User “张三” 20
命名传参:Greet-User -Name “张三” -Age 20
- 在函数中输出结果,推荐使用 Write-Output(可以省略不写,直接写变量或字符串,默认就是输出到管道)。这与 Write-Host 不同,Write-Output 会将对象写入管道,方便后续脚本进行二次处理(例如 | Out-File 写入文件)
DOS常见指令
Shell 实验指令与脚本汇总
一、指令知识点总表
| 类别 | 指令 / 语法 | 作用 | 示例 | 对应题目 |
|---|---|---|---|---|
| 文件系统 | dir | 列出目录内容 | dir | 任务 1 |
| 文件系统 | dir /s | 递归列出子目录内容 | dir /s | 任务 1 |
| 文件系统 | dir /p | 分页显示 | dir /p | 任务 1 |
| 文件系统 | dir /? | 查看命令帮助 | dir /? | 任务 1 |
| 文件系统 | cd | 切换目录 | cd D:\Lecture | 任务 1 |
| 文件系统 | cd .. | 返回上级目录 | cd .. | 任务 1 |
| 屏幕 | cls | 清屏 | cls | 任务 1 |
| 中断 | Ctrl + C | 停止当前命令 | dir /s后按 | 任务 1 |
| 批处理 | @echo off | 关闭命令回显 | @echo off | 任务 2 |
| 批处理 | REM | 注释 | REM 这是注释 | 任务 2 |
| 输出 | echo | 输出字符串 | echo Hello | 任务 2、3 |
| 输出 | echo. | 输出空行 | echo. | 任务 2、3 |
| 参数 | %1 | 第一个参数 | echo %1 | 任务 2、3、4、5、6、7 |
| 参数 | %2 | 第二个参数 | tasklist /FI "PID le %2" | 任务 6 |
| 文件筛选 | DIR %1\*.txt | 列出指定目录 txt 文件 | DIR %1\*.txt | 任务 3 |
| 文件筛选 | DIR %1\*.pdf | 列出指定目录 pdf 文件 | DIR %1\*.pdf | 任务 3 |
| 条件 | IF | 条件判断 | IF "%1"=="1" echo ... | 任务 4 |
| 条件 | IF NOT | 反向判断 | IF NOT "%1"=="3" echo ... | 任务 4 |
| 条件 | IF ... ELSE IF ... ELSE | 多分支判断 | IF "%1"=="" (...) ELSE ... | 任务 6 |
| 变量 | SET | 设置变量 | SET end=%1 | 任务 5 |
| 循环 | FOR /L %%G IN (1,1,%1) DO | 计数循环 | FOR /L %%G IN (1,1,10) DO echo %%G | 任务 5 |
| 进程 | tasklist | 列出进程 | tasklist | 任务 6、7 |
| 进程 | tasklist /FI "PID ge %1" | 过滤 PID >= 参数 | tasklist /FI "PID ge 100" | 任务 6 |
| 进程 | tasklist /FI "PID le %2" | 过滤 PID <= 参数 | tasklist /FI "PID le 500" | 任务 6 |
| 进程 | tasklist /FI "PID lt %1" | 过滤 PID < 参数 | tasklist /FI "PID lt 1000" | 任务 7 |
| Linux | #!/bin/bash | 指定 Bash 解释器 | #!/bin/bash | Linux 实验 |
| Linux | chmod +x | 添加执行权限 | chmod +x cpu_usage.sh | Linux 实验 |
| Linux | ./脚本.sh | 运行脚本 | ./cpu_usage.sh | Linux 实验 |
| Linux | ps -eo | 自定义进程输出列 | ps -eo pid,user,%cpu,%mem,comm | Linux 实验 |
| Linux | --sort=-%cpu | 按 CPU 降序排序 | ps ... --sort=-%cpu | Linux 实验 |
| Linux | awk | 文本过滤 | awk 'NR==1 || $3 > 0.0' | Linux 实验 |
| Linux | NR==1 | 保留标题行 | awk 'NR==1 ...' | Linux 实验 |
| Linux | $3 > 0.0 | 第三列大于 0.0 | awk '$3 > 0.0' | Linux 实验 |
二、DOS / CMD 题目脚本
@echo off REM scriptname: myname.bat REM scriptfunction: display basic batch processing commands, receive parameters and output REM creatingdate: 2026-9-21 echo myname.bat is now running echo. echo Hello %1!—
@echo off REM 1.output script running prompt echo Listing files under diectory %1 ... REM 2.output a blank line echo. REM 3.list %1\*.txt dir "%1\*.txt" REM 4.output a blank line echo. REM 5.list %1\*.pdf dir "%1\*.pdf" pause@echo off IF "%1"=="" ( echo Usage: testif 1/2/3 exit /b ) REM IF statement that must be used IF "%1"=="1" echo you enter 1 IF "%1"=="2" echo You enter 2 IF NOT "%1"=="3" echo It was not 3!!!@echo off REM assign the first passed parameter to the variable 'end' SET end=%1 FOR /L %%G IN (1,1,%end%) DO echo repetition n. %%G@echo off echo Processes with PID within a given range echo. if "%~1"=="" ( REM without parameters:print all processes tasklist ) else if "%~2"=="" ( REM with a parameter: print PID >= parameter1 process tasklist /FI "PID ge %1" ) else ( REM with 2 parameters: print PID >= parameter1 and PID <= parameter2 process tasklist /FI "PID ge %1" /FI "PID le %2" )@echo off if "%~1"=="" ( echo [usage] printpid.bat [PID upper limit] echo [default]no parameter provided ,using default upper limit 1000 set "limit=1000" )else ( set "limit=%~1" ) tasklist /FI "PID lt %limit%"2026年9月27号,我在大二上学期写下了人生的第一篇博客,我想把他作为我知识管理的工具,培养输出型习惯。格式上会比较没有章法,会慢慢找到自己的风格。作为双非信安,虽然自己起步较晚,玩了一年。但我的梦想依旧滚烫,我仍然会朝着自己的理想不断前进!