使用Where-Object与StartsWith过滤PowerShell输出时遇空值错误求助
问题描述
使用他人编写的PowerShell脚本过滤docker info输出提取结果时出现报错,脚本相关代码:
$dockerInfo = (docker info) $dockerOsMode = ($dockerInfo | Where-Object { $_.StartsWith('OSType: ') }).SubString(8)
遇到的错误信息:
Checking Docker Service Settings... You cannot call a method on a null-valued expression. At C:\Users\MichaelC\Documents\DockerCleanup.ps1:29 char:1 + $dockerOsMode = ($dockerInfo | Where-Object { $_.StartsWith('OSType: ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvokeMethodOnNull
确认$dockerInfo变量不为空,直接输出可见完整内容:
PS C:\Users\MichaelC> $dockerinfo Client: Version: 24.0.4 Context: default Debug Mode: false Server: Containers: 2 Running: 0 Paused: 0 Stopped: 2 Images: 47 Server Version: 24.0.4 Storage Driver: windowsfilter Windows: Logging Driver: json-file Plugins: Volume: local Network: ics internal l2bridge l2tunnel nat null overlay private transparent Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog Swarm: inactive Default Isolation: process Kernel Version: 10.0 17763 (17763.1.amd64fre.rs5_release.180914-1434) Operating System: Microsoft Windows Server Version 1809 (OS Build 17763.5329) OSType: windows Architecture: x86_64 CPUs: 6 Total Memory: 31.98GiB Name: MCNAV ID: 5dbd48b8-ca1b-44bf-9495-5a504c435305 Docker Root Dir: D:\docker Debug Mode: false Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Product License: Community Engine
疑问:是否需要开启其他全局设置才能对命令输出使用过滤命令?
问题原因与解决办法
原因
报错核心是Where-Object未匹配到任何结果,返回了$null,后续调用.SubString(8)触发“空值表达式无法调用方法”的错误。
明明输出里有OSType: windows却匹配失败,大概率是目标行存在隐藏空白:比如行首有缩进空格/制表符,或者OSType:后的空格数量和脚本里的'OSType: '不一致,导致StartsWith匹配失效。
解决办法
方案1:用正则匹配忽略空白(兼容格式波动)
改用正则表达式匹配,自动忽略行首和OSType:后的空白,直接提取值:
$dockerOsMode = ($dockerInfo | Where-Object { $_ -match '^\s*OSType:\s*(.*)' } | ForEach-Object { $matches[1] })
^\s*匹配行首任意数量的空白(空格/制表符)OSType:\s*匹配OSType:及其后任意空白(.*)捕获操作系统类型值,通过$matches[1]直接提取
方案2:先清理空白再精准匹配
先去除每行首尾空白,再用StartsWith匹配:
$dockerOsMode = ($dockerInfo | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('OSType:') }).SubString(8).Trim()
.Trim()去掉每行首尾空白,包括行首缩进和行尾换行符- 匹配后截取并清理值的空白,确保结果干净
方案3:用Docker JSON输出(最稳定)
直接让docker info输出JSON格式,通过PowerShell解析结构,彻底避免字符串匹配问题:
$dockerInfo = docker info --format '{{json .}}' | ConvertFrom-Json $dockerOsMode = $dockerInfo.OSType
这种方式依赖Docker的结构化输出,不会因为缩进、空格等格式小变化导致失败,是最可靠的方案。
内容的提问来源于stack exchange,提问作者TNPMCHammer
相关产品推荐
相关产品推荐

