当前位置: 首页 > news >正文

PowerShell 第18章:变量,把数据装进“盒子”的正确方式


🔥个人主页:杨利杰YJlio
❄️个人专栏:《Sysinternals实战教程》 《Windows PowerShell 实战》 《WINDOWS教程》 《IOS教程》
《微信助手》 《锤子助手》 《Python》 《Kali Linux》
《那些年未解决的Windows疑难杂症》
🌟让复杂的事情更简单,让重复的工作自动化


PowerShell 第18章:变量,把数据装进“盒子”的正确方式

  • 1. 写在前面:为什么变量是脚本化的第一步?
  • 2. 什么是变量:有名字的内存盒子
    • 2.1 创建变量
    • 2.2 读取变量
    • 2.3 查看变量对象类型
    • 2.4 在命令中使用变量
  • 3. 引号、转义与子表达式:变量插值最容易出错的地方
    • 3.1 单引号:原样输出
    • 3.2 双引号:支持变量插值
    • 3.3 转义字符:反引号 `
    • 3.4 子表达式 `$()`:复杂插值必须用它
  • 4. 数组与集合:一次保存多个值
    • 4.1 查看数组数量
    • 4.2 访问第一个元素
    • 4.3 访问最后一个元素
    • 4.4 数组常用操作速查
  • 5. 自动展开 automatic unrolling:v3+ 的实用特性
    • 5.1 自动展开的好处
    • 5.2 自动展开的兼容性提醒
    • 5.3 修改集合内容要重新赋值
  • 6. 核心命令与操作流程:从赋值到持久化
    • 6.1 创建变量
    • 6.2 查看变量内容
    • 6.3 查看变量类型
    • 6.4 命令里使用变量
    • 6.5 保存对象集合
    • 6.6 导出对象到 CliXML
    • 6.7 导入对象
  • 7. 强类型变量:让错误更早暴露
    • 7.1 为什么要加类型约束?
    • 7.2 常见类型速查
    • 7.3 重新指定变量类型
  • 8. 变量相关 Cmdlet:知道即可,不必滥用
    • 8.1 查看变量
    • 8.2 创建变量
    • 8.3 修改变量
    • 8.4 清空变量值
    • 8.5 删除变量
    • 8.6 实战建议
  • 9. 常见问题与易错点:新手最容易踩的 5 类坑
    • 9.1 错误一:混淆单引号和双引号
    • 9.2 错误二:复杂插值不用 `$()`
    • 9.3 错误三:忘记 `Read-Host` 默认返回字符串
    • 9.4 错误四:以为变量会永久保存
    • 9.5 错误五:跨版本忽略自动展开差异
  • 10. Mermaid:变量学习路线图
  • 11. 动手练习:把变量真正用起来
    • 11.1 练习一:查询 BIOS 并保存到变量
    • 11.2 练习二:导出为 CliXML
    • 11.3 练习三:安全读取数字并乘以 10
    • 11.4 练习四:拼接服务名
    • 11.5 练习五:数组全部转小写
  • 12. 总结复盘:变量是可复用脚本的起点
  • 参考命令

1. 写在前面:为什么变量是脚本化的第一步?

在学习 PowerShell 时,很多人一开始只会执行“一次性命令”:

Get-ServiceGet-ProcessGet-WmiObjectWin32_BIOS

这些命令可以解决临时问题,但如果想把命令变成可复用脚本,就必须掌握变量。

变量的本质很简单:它就是一个有名字的内存盒子。

我们可以把字符串、数字、对象、数组、XML、命令结果放进去,然后在后面的命令里继续使用。

一句话理解:变量让 PowerShell 从“一次性命令”进化为“可复用脚本”。

本文围绕 PowerShell 第 18 章“变量”进行整理,重点讲清楚:

  • 变量是什么;
  • 如何创建、读取、复用变量;
  • 单引号、双引号、转义和子表达式的区别;
  • 数组与对象集合怎么处理;
  • PowerShell v3+ 自动展开机制是什么;
  • 为什么要使用强类型变量;
  • 新手最容易踩哪些坑;
  • 如何把变量用于企业运维脚本。

从上图可以看到,变量不是单纯的“文本替换”,而是 PowerShell 脚本中的数据容器。它可以保存字符串、数字、对象、数组和 XML 等内容。

如果你想写出稳定、可维护、可复用的 PowerShell 脚本,变量是必须先掌握的基础能力。


2. 什么是变量:有名字的内存盒子

变量可以理解为一个“盒子”。

这个盒子有两个核心组成:

变量名 + 变量值

例如:

$var="SERVER-R2"

这里:

  • $var是变量;
  • var是变量名;
  • "SERVER-R2"是变量值;
  • $是 PowerShell 用来识别变量的符号。

严格来说,变量名不是$var,而是var$只是访问变量时使用的前缀。

2.1 创建变量

$computer="SERVER-R2"

这行命令的意思是:
把字符串"SERVER-R2"放进名为$computer的变量中。

2.2 读取变量

$computer

执行后会输出:

SERVER-R2

2.3 查看变量对象类型

PowerShell 是对象型 Shell,变量里保存的不只是文本。

可以用Get-Member查看变量到底是什么类型:

$computer|Get-Member

你会看到它是:

System.String

这说明字符串在 PowerShell 里也是对象,并且拥有自己的方法和属性。

这就是 PowerShell 和传统 CMD 最大的区别之一:PowerShell 处理的是对象,不只是文本。

2.4 在命令中使用变量

变量最常见的用途,是把值放进命令参数里。

例如:

$computer="SERVER-R2"Get-WmiObjectWin32_ComputerSystem-ComputerName$computer

这里$computer会被解析为SERVER-R2,然后作为-ComputerName参数值传给命令。


3. 引号、转义与子表达式:变量插值最容易出错的地方

变量学起来不难,真正容易踩坑的是字符串中的变量替换。

尤其是:

  • 单引号;
  • 双引号;
  • 反引号转义;
  • $()子表达式;
  • 数组属性访问;
  • 自动展开机制。

这张图非常适合用来理解变量插值机制:
单引号原样输出,双引号支持变量替换,复杂表达式必须使用$()

3.1 单引号:原样输出

单引号不会替换变量。

$computer='SERVER-R2'$single='computer is $computer'$single

输出结果:

computer is$computer

可以看到,$computer没有被替换。

单引号适合写“原样字符串”,特别适合路径、模板、正则、示例文本等场景。

3.2 双引号:支持变量插值

双引号会把变量替换成实际值。

$computer='SERVER-R2'$double="computer is$computer"$double

输出结果:

computer is SERVER-R2

需要在字符串中拼接变量值时,优先使用双引号。

3.3 转义字符:反引号 `

PowerShell 使用反引号作为转义字符。

例如,如果想在字符串中显示$本身,而不是变量替换,可以这样写:

$computer='SERVER-R2'$phrase="`$computer=$computer"$phrase

输出:

$computer= SERVER-R2

常见转义字符包括:

转义写法含义
`$输出$本体
`n换行
`t制表符
`a蜂鸣

注意:PowerShell 的转义符是反引号,不是单引号。新手经常把二者看混。

3.4 子表达式$():复杂插值必须用它

当字符串中需要访问对象属性、数组索引或复杂表达式时,必须使用$()

错误写法:

$services=Get-Service$msg="First service is$services[0].Name"$msg

这通常不会得到你想要的结果。

正确写法:

$services=Get-Service$msg="First service is$($services[0].Name)"$msg

为什么?

因为$services[0].Name不是简单变量,而是:

变量 + 索引 + 属性

PowerShell 需要先计算$services[0].Name,再把结果放进字符串中。

记忆方法:只要字符串里出现属性、索引、计算表达式,就用$()包起来。


4. 数组与集合:一次保存多个值

变量不仅能保存一个值,也能保存多个值。

例如:

$computers='SRV1','SRV2','localhost'

此时$computers是一个数组。

4.1 查看数组数量

$computers.Count

输出:

3

4.2 访问第一个元素

$computers[0]

输出:

SRV1

PowerShell 数组索引从0开始。

4.3 访问最后一个元素

$computers[-1]

输出:

localhost

负数索引是 PowerShell 中非常实用的小技巧,[-1]表示倒数第一个元素。

4.4 数组常用操作速查

操作示例说明
获取数量$computers.Count返回元素数量
第一个元素$computers[0]获取数组第一个值
最后一个元素$computers[-1]获取数组最后一个值
遍历数组ForEach-Object对每个元素执行操作

5. 自动展开 automatic unrolling:v3+ 的实用特性

PowerShell v3 以后,访问集合属性时会自动枚举集合中的每个对象。

例如:

$services=Get-Service$services.Name

这会输出所有服务的名称。

它等价于:

Get-Service|Select-Object-ExpandProperty Name

或者:

Get-Service|ForEach-Object{$_.Name}

5.1 自动展开的好处

它让代码更短:

$services.Name

比下面写法更简洁:

$services|ForEach-Object{$_.Name}

5.2 自动展开的兼容性提醒

PowerShell v1/v2 不支持这种自动展开行为。

如果你的脚本需要兼容老版本 PowerShell,建议使用更稳妥的写法:

$services|Select-Object-ExpandProperty Name

5.3 修改集合内容要重新赋值

例如把主机名全部转为小写:

$computers='SRV1','SRV2','LOCALHOST'$computers=$computers|ForEach-Object{$_.ToLower()}

这里必须重新赋值给$computers

管道输出的新结果不会自动覆盖原变量,必须显式写回。


6. 核心命令与操作流程:从赋值到持久化

下面这张图把变量的常用操作流程串起来了。

可以按照这个顺序学习:

创建变量 → 查看类型 → 批量处理数组 → 类型约束 → 导入导出持久化

6.1 创建变量

$var="SERVER-R2"

6.2 查看变量内容

$var

6.3 查看变量类型

$var|Get-Member

6.4 命令里使用变量

Get-WmiObjectWin32_ComputerSystem-ComputerName$var

6.5 保存对象集合

$services=Get-Service

6.6 导出对象到 CliXML

$services|Export-Clixml.\services.xml

6.7 导入对象

$back=Import-Clixml.\services.xml

如果想保留对象结构,Export-Clixml比普通文本更适合 PowerShell 脚本场景。


7. 强类型变量:让错误更早暴露

PowerShell 默认不强制要求你声明变量类型。

例如:

$x= 100$x="Hello"

这在 PowerShell 中是允许的。

但在一些场景下,我们反而希望变量必须是某种类型。

7.1 为什么要加类型约束?

例如下面这段:

$n=Read-Host"Enter a number"$n*10

Read-Host返回的是字符串。

如果用户输入的是5,看起来没问题。
但如果后续涉及比较、计算、类型转换,就可能出现隐藏问题。

更安全的写法是:

[int]$n=Read-Host"Enter a number"$n*10

如果输入不是数字,PowerShell 会直接报错。

强类型变量的价值是:让错误尽早暴露,而不是在脚本后面才出现奇怪结果。

7.2 常见类型速查

类型说明示例
[int]整数[int]$n = 10
[string]字符串[string]$name = "abc"
[double]双精度浮点[double]$price = 12.5
[single]单精度浮点[single]$x = 1.2
[char]单个字符[char]$c = 'A'
[xml]XML 文档[xml]$doc = Get-Content .\a.xml
[adsi]ADSI 对象[adsi]$user = "WinNT://..."

7.3 重新指定变量类型

[int]$x= 5

此时:

$x="Hello"

会报错,因为"Hello"无法转换成整数。

如果确实要改成字符串,可以重新声明:

[string]$x="Hello"

类型约束不是越多越好,而是应该用在输入、计算、比较、配置参数等关键位置。


8. 变量相关 Cmdlet:知道即可,不必滥用

PowerShell 提供了一组变量相关 Cmdlet:

Get-VariableSet-VariableNew-VariableClear-VariableRemove-Variable

8.1 查看变量

Get-Variable

查看指定变量:

Get-Variablecomputer

注意这里不写$

8.2 创建变量

New-Variable-Name computer-Value"SERVER-R2"

等价于:

$computer="SERVER-R2"

8.3 修改变量

Set-Variable-Name computer-Value"SERVER01"

等价于:

$computer="SERVER01"

8.4 清空变量值

Clear-Variable-Name computer

8.5 删除变量

Remove-Variable-Name computer

8.6 实战建议

日常脚本中,优先使用:

$var=...

变量 Cmdlet 更多用于:

  • 元编程;
  • 作用域控制;
  • 动态变量名;
  • 模块脚本;
  • 调试变量;
  • 特殊场景自动化。

普通脚本不要为了“显得高级”而滥用变量 Cmdlet,直接赋值最清晰。


9. 常见问题与易错点:新手最容易踩的 5 类坑

下面这张图总结了变量学习中最常见的错误。

重点记住一句话:

变量本身不难,难点主要在引号、类型、兼容性和持久化。

9.1 错误一:混淆单引号和双引号

错误理解:

'computer is $computer'

以为会输出变量值。

实际输出:

computer is$computer

正确写法:

"computer is$computer"

9.2 错误二:复杂插值不用$()

错误写法:

"$services[0].Name"

正确写法:

"$($services[0].Name)"

属性、索引、表达式,只要进字符串,就用$()

9.3 错误三:忘记Read-Host默认返回字符串

$n=Read-Host"Enter a number"

这里$n是字符串,不是数字。

推荐:

[int]$n=Read-Host"Enter a number"

9.4 错误四:以为变量会永久保存

PowerShell 会话关闭后,普通变量会消失。

如果需要保存结果,应导出:

$services|Export-Clixml.\services.xml

或者导出为 CSV:

$services|Export-Csv.\services.csv-NoTypeInformation

9.5 错误五:跨版本忽略自动展开差异

PowerShell v3+ 支持:

$services.Name

但如果脚本需要兼容旧版本,建议写成:

$services|Select-Object-ExpandProperty Name

10. Mermaid:变量学习路线图

可以把 PowerShell 变量学习路线整理成下面这张图:

渲染错误:Mermaid 渲染失败: Parse error on line 6: ... E --> F[使用子表达式 $()] F --> G[学习数组 -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'

这条路线非常适合新手:

  1. 先知道变量是什么;
  2. 再知道怎么赋值和读取;
  3. 再理解引号和字符串插值;
  4. 然后掌握数组、对象集合;
  5. 最后加入类型约束和持久化。

变量学习不是孤立知识点,它是脚本参数、函数、配置文件、批量处理的基础。


11. 动手练习:把变量真正用起来

11.1 练习一:查询 BIOS 并保存到变量

要求:
把两台机器的 BIOS 查询结果放入变量$bios

参考答案:

$bios=Invoke-Command{Get-WmiObjectWin32_BIOS}-ComputerName localhost,$env:COMPUTERNAME

查看结果:

$bios

11.2 练习二:导出为 CliXML

$bios|Export-Clixml-Path.\bios.xml

再次导入:

$biosBack=Import-Clixml-Path.\bios.xml$biosBack

CliXML 适合保存 PowerShell 对象结构,比普通 TXT 更适合脚本复用。

11.3 练习三:安全读取数字并乘以 10

[int]$n=Read-Host"Enter a number"$n*10

如果用户输入非数字,会直接报错。

这比后面计算出错更容易定位问题。

11.4 练习四:拼接服务名

$svcs=Get-Service$msg="First is$($svcs[0].Name). All:$($svcs.Name-join', ')"$msg

这里有两个关键点:

  • $($svcs[0].Name)用于取第一个服务名;
  • $($svcs.Name -join ', ')用于把所有服务名拼成字符串。

11.5 练习五:数组全部转小写

$computers='SRV1','SRV2','LOCALHOST'$computers=$computers|ForEach-Object{$_.ToLower()}$computers

输出:

srv1 srv2 localhost

12. 总结复盘:变量是可复用脚本的起点

最后用一张图把本文内容收住。

变量不是一个孤立语法点,而是 PowerShell 自动化脚本的基础能力。

本文核心结论如下:

  1. 变量是有名字的内存盒子。
  2. PowerShell 变量可以保存字符串、数字、对象、数组和 XML。
  3. 单引号原样输出,双引号支持变量替换。
  4. 复杂字符串插值必须使用$()子表达式。
  5. 数组可以通过索引访问,[-1]表示最后一个元素。
  6. PowerShell v3+ 支持集合属性自动展开。
  7. Read-Host默认返回字符串,需要计算时建议加[int]等类型约束。
  8. 普通变量只在当前会话存在,持久化需要导出为 CSV、CliXML 或 JSON。
  9. 变量 Cmdlet 知道即可,日常脚本优先直接赋值。
  10. 学好变量,后面学习函数、参数、模块、批量运维会轻松很多。

我的理解是:变量 = 复用数据的起点;数组 = 批量处理的基础;类型约束 = 提前发现错误;持久化 = 脚本可复用的关键。

建议学习顺序:先赋值与读取,再学引号与$(),然后学数组和自动展开,最后学类型与持久化。

不要小看变量。很多脚本写不稳,不是因为命令不会,而是变量、类型、字符串插值和对象集合没理解透。

一句话记住本章:

PowerShell 变量不是简单文本替换,而是把对象、集合和命令结果组织起来,让脚本真正可复用。


参考命令

Get-Helpabout_VariablesGet-Helpabout_Quoting_RulesGet-Helpabout_Escape_CharactersGet-Helpabout_ScopeGet-HelpExport-ClixmlGet-HelpImport-Clixml

🔝 返回顶部

点击回到顶部

http://www.jsqmd.com/news/739752/

相关文章:

  • 04华夏之光永存・保姆级开源:黄大年茶思屋榜文解法「27期 4题」 高性能语义分析引擎 保姆级完整解法
  • 猫抓浏览器扩展终极指南:5分钟掌握网页资源嗅探神器
  • E7Helper:第七史诗自动化助手,解放你的游戏时间
  • Torchmeta源码架构分析:理解元学习框架的设计哲学
  • InstaLooter安全使用指南:如何保护你的Instagram账号
  • 别再手动敲空格了!LaTeX表格标题间距调整的三种高效方法(附代码示例)
  • 利用Taotoken多模型能力为不同编程任务匹配合适的Codex模型
  • AI信息摘要系统构建指南:从数据采集到LLM应用实战
  • CodeMaker架构深度解析:IntelliJ IDEA智能代码生成插件的设计哲学与实践
  • VisualEffectGraph-Samples核心组件详解:粒子系统、着色器与动画的完美结合
  • 解密Dexter核心原理:HypoPG如何实现假设性索引分析
  • 通过 OpenClaw 配置 Taotoken 作为 Agent 工作流后端的详细教程
  • 中断不触发?断点失效?RISC-V调试失败全场景归因分析,附可复现测试用例集
  • 掌握Vue.js事件处理:从阻止传播到键盘修饰符的实战指南
  • 构建可重复的智能雨洪模型工作流:从SWMM自动化到AI智能体集成
  • 用 X.509 Client Certificate 把 SAP NetWeaver 登录做成真正的无感 SSO
  • ElaWidgetTools卡片组件大全:交互式、亚克力、热门卡片实战
  • React Hooks调试与测试:从入门到精通的完整工作流和工具链指南
  • C++引用与指针:核心区别与实战解析
  • OpenTrader开发者进阶指南:深入理解事件驱动架构与策略执行流程
  • 山东五一集训2026
  • 终极指南:如何在Mac上一键解锁QQ音乐加密歌曲,实现真正的音乐自由
  • 如何快速构建REST API集成:Budibase低代码平台终极指南
  • 【稀缺首发】Python 3.15 beta2中未公开的类型系统彩蛋:LiteralString强化、Never类型收敛优化及VS Code 1.96智能补全适配方案
  • 效果展示,Taotoken按Token计费模式如何帮助小项目控制成本
  • 探索RBBAnimation的未来:新特性与路线图展望
  • Elsevier投稿系统Editorial Manager实操:Cover Letter怎么写?审稿人怎么选?
  • Fan Control终极指南:Windows风扇控制软件完美中文显示解决方案
  • 告别经纬度!用Python实战解析国家地球网格标准(附32级编码生成代码)
  • 前端面试终极指南:如何通过用户体验优化赢得大厂Offer