PowerShell脚本报错:空值表达式调用及重复键问题求助
PowerShell脚本调试问题
原始代码(第66行)
$remotefilehash = ($remoteFiles | Where-Object { -not ($_ | Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') } -replace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData
初始报错信息
Where-Object : A parameter cannot be found that matches parameter name 'replace'. At P:\scripts\code\pcloud_sync.ps1:66 char:125 + ... ing -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') } -replace '^[a-f0 ... + ~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.WhereObjectCommand You cannot call a method on a null-valued expression. At P:\scripts\code\pcloud_sync.ps1:74 char:1 + $diffmd5 = $remotefilehash.GetEnumerator().Where({ -not $localHashSet ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
更新代码后的新报错
添加括号修正语法后,出现重复键报错:
ConvertFrom-StringData : Data item 'a3512c98c9e159c021ebbb76b238707e' in line 'a3512c98c9e159c021ebbb76b238707e = My Pictures/Tony/Automatic Upload/Tony’s iPhone/2022-10-08 21-46-21 (2).mov' is already defined. At P:\scripts\code\pcloud_sync.ps1:66 char:179 + ... ace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [ConvertFrom-StringData], PSInvalidOperationException + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand You cannot call a method on a null-valued expression. At P:\scripts\code\pcloud_sync.ps1:74 char:1 + $diffmd5 = $remotefilehash.GetEnumerator().Where({ -not $localHashSet ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
解决方案
1. 修复管道语法错误
初始报错是因为-replace被错误当作Where-Object的参数,需将Where-Object的过滤结果用括号包裹,确保-replace作用在过滤后的字符串集合上:
$remotefilehash = (($remoteFiles | Where-Object { -not ($_ | Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') }) -replace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData
2. 处理$remoteFiles为空的情况
为避免空值导致后续操作报错,先确保$remoteFiles始终是数组类型,即使为空也不会返回$null:
$remoteFiles = @($remoteFiles) # 强制转为数组
或者在处理前添加空值判断:
if (-not $remoteFiles) { $remotefilehash = @{} # 可根据需求添加空值场景下的后续逻辑 } else { # 执行转换逻辑 }
3. 解决重复MD5键问题
ConvertFrom-StringData不允许重复键值对,需先按MD5值对过滤后的行去重。以下是保留每组最后一个重复项的处理方式:
# 过滤符合MD5格式的行 $filteredLines = $remoteFiles | Where-Object { -not ($_ | Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') } # 按MD5值分组,保留每组最后一行 $uniqueLines = $filteredLines | Group-Object { $_ -replace '^([a-f0-9]{32})\s{2}.*', '$1' } | ForEach-Object { $_.Group[-1] } # 转换为键值对哈希表 $remotefilehash = ($uniqueLines -replace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

