启动并区分 PowerShell 5.1 与 7.x,管理脚本环境。
PowerShell 是面向对象的命令行外壳和脚本语言:cmdlet 输出 .NET 对象而不是文本,管道传递对象,因此可以用 Where-Object、Select-Object 继续加工。Windows 自带的是 powershell.exe(5.1,.NET Framework),pwsh.exe 是独立安装的 7.x(.NET),两者并存且配置、模块路径不同;用 $PSVersionTable 的 PSEdition(Desktop/Core)判断。PowerShell 是宿主程序而不是 cmdlet,没有管道输出和别名;具体命令通过 powershell.exe 或 pwsh.exe 启动。
边界:执行策略(Execution Policy)只限制脚本加载,不是安全边界,不能代替 ACL、签名和最小权限;它也不影响交互式命令和 -Command 字符串。$PROFILE 中的函数、别名和模块会改变命令解析结果,排障和计划任务要用 -NoProfile 复现干净环境。32 位与 64 位进程看到的注册表和 System32 不同(SysWOW64 重定向)。
权限:运行交互式会话通常不需要管理员;系统级安装 7.x、写入系统级模块目录、执行需要提权的 cmdlet 才需要管理员。7.x 差异:只有 pwsh 支持 ForEach-Object -Parallel、三元运算符等新语法;5.1 不支持这些语法,脚本若要兼容 5.1 就不要使用。
# 1. 确认版本、版本线和宿主,排障第一步
PS C:\> $PSVersionTable | Format-List
# 2. 用干净会话执行一条命令,排除 profile 干扰
PS C:\> powershell.exe -NoProfile -Command "(Get-CimInstance Win32_OperatingSystem).Caption"
# 3. 7.x 差异:用 pwsh 执行脚本文件,参数按 -File 传入
PS C:\> pwsh -NoProfile -File .\report.ps1 -Days 7
# 4. 查看各作用域的执行策略,定位“脚本被阻止”来自哪一层
PS C:\> Get-ExecutionPolicy -List
# 5. 确认当前进程位数,排查注册表和 System32 重定向
PS C:\> [Environment]::Is64BitProcess; [Environment]::Is64BitOperatingSystem
# 6. 统计当前会话可见的管理类命令数量
PS C:\> (Get-Command -Module Microsoft.PowerShell.Management).Count
powershell 却用了 7.x 语法,表现为语法错误或参数不存在;原因是 powershell.exe 固定是 5.1。验证:powershell.exe -NoProfile -Command '$PSVersionTable.PSVersion',需要 7.x 时显式调用 pwsh.exe。Get-ExecutionPolicy -List 看生效值。修正是按组织策略使用签名脚本或 RemoteSigned,不要长期绕过。-NoProfile 下不存在;用 $PROFILE 定位,再在脚本里显式定义依赖。-Command 外层引号被调用方 shell 吃掉,变量提前展开;把整段命令用单引号包住,复杂逻辑改用 -File 脚本。C:\Windows\System32 会被重定向到 SysWOW64,注册表 HKLM:\Software 也可能看到 Wow6432Node;用 [Environment]::Is64BitProcess 验证。$Host.Version 是宿主版本,不等于语言版本;判断 5.1/7.x 始终看 $PSVersionTable.PSVersion 和 PSEdition。Get-Command — 查命令来源、类型和参数。Get-Help — 查语法、示例和 about_ 主题。Get-ChildItem — 最常见的对象管道入口。合上页面,先回答,再展开对照。
-NoProfile,复杂命令为什么优先 -File?$PSVersionTable.PSVersion 和 PSEdition:5.1 是 Desktop,7.x 是 Core;再看宿主是 powershell.exe 还是 pwsh.exe。-NoProfile 排除 profile 的函数、别名和模块副作用;-File 避免多层引号和变量提前展开。
小程序版
微信扫码,随时查命令