Powershell Select-对象-和哈希
Powershell Select-Object - and Hash
谁能告诉我这有什么问题吗?
$MD5Hashes = @{}
Get-ChildItem "C:\Users\Tony\Pictures\My Pictures09" -Recurse -File | Select-Object -ExpandProperty FullName,Name | % {
$MD5Hashes.Add($_.Name, (Get-FileHash $_.FullName -Algorithm MD5))
}
这是错误:
Exception calling "Add" with "2" argument(s): "Key cannot be null. Parameter name: key" At C:\Users\Tony\Documents\pcloud_sync.ps1:3 char:3
+ $MD5Hashes.Add($_.FullName, (Get-FileHash $_ -Algorithm MD5))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
我可以看到 $_ 正在获取 FullName 变量,但不确定 .Name 没有通过什么,而且 Get-FileHash 逻辑中似乎也没有填充任何内容...
powershell 有点新...
继续我的评论:
当使用 -ExpandProperty
时,您正在检索一个 属性 的 值 ,而您的代码试图同时获取全名和文件名.
代码的其余部分仍然使用 $_.Name
,就好像您选择了具有属性的 objects,但是由于 -ExpandProperty
,情况不再如此。
解决这个问题的简单方法是删除 -ExpandProperty
开关或实际上删除整个部分 | Select-Object -ExpandProperty FullName,Name
。
下一个:
要添加到 Hashtable,您可以使用其 Add()
方法,但是当您尝试添加一个 属性 且其键名已被使用时,这将引发异常。
由于您想递归地获取文件名,因此很可能会出现来自不同文件夹的同名文件。
要克服从 $MD5Hashes.Add()
中获取错误,您可以先使用测试:
if (!$MD5Hashes.ContainsKey($_.Name)) {
# get the hash **value** from the returned object of Get-FileHash
$md5 = (Get-FileHash $_.FullName -Algorithm MD5).Hash
$MD5Hashes.Add($_.Name, $md5)
}
但这会导致在出现同名文件时跳过文件哈希,这意味着只存储 第一个 文件名,所有重复的文件名都将丢失。
另一种方法是直接将属性分配给哈希表:
$MD5Hashes[$_.Name] = (Get-FileHash $_.FullName -Algorithm MD5).Hash
虽然现在您不会抛出异常,但这将 覆盖 任何已经存在的项目,这意味着 last 文件有一个副本名称将被存储而其他人将丢失。
因此,我建议您使用文件的 FullName
作为哈希表的键,以确保哈希表中不会出现重复的键,并且不会丢失任何内容。
谁能告诉我这有什么问题吗?
$MD5Hashes = @{}
Get-ChildItem "C:\Users\Tony\Pictures\My Pictures09" -Recurse -File | Select-Object -ExpandProperty FullName,Name | % {
$MD5Hashes.Add($_.Name, (Get-FileHash $_.FullName -Algorithm MD5))
}
这是错误:
Exception calling "Add" with "2" argument(s): "Key cannot be null. Parameter name: key" At C:\Users\Tony\Documents\pcloud_sync.ps1:3 char:3
+ $MD5Hashes.Add($_.FullName, (Get-FileHash $_ -Algorithm MD5))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
我可以看到 $_ 正在获取 FullName 变量,但不确定 .Name 没有通过什么,而且 Get-FileHash 逻辑中似乎也没有填充任何内容...
powershell 有点新...
继续我的评论:
当使用 -ExpandProperty
时,您正在检索一个 属性 的 值 ,而您的代码试图同时获取全名和文件名.
代码的其余部分仍然使用 $_.Name
,就好像您选择了具有属性的 objects,但是由于 -ExpandProperty
,情况不再如此。
解决这个问题的简单方法是删除 -ExpandProperty
开关或实际上删除整个部分 | Select-Object -ExpandProperty FullName,Name
。
下一个:
要添加到 Hashtable,您可以使用其 Add()
方法,但是当您尝试添加一个 属性 且其键名已被使用时,这将引发异常。
由于您想递归地获取文件名,因此很可能会出现来自不同文件夹的同名文件。
要克服从 $MD5Hashes.Add()
中获取错误,您可以先使用测试:
if (!$MD5Hashes.ContainsKey($_.Name)) {
# get the hash **value** from the returned object of Get-FileHash
$md5 = (Get-FileHash $_.FullName -Algorithm MD5).Hash
$MD5Hashes.Add($_.Name, $md5)
}
但这会导致在出现同名文件时跳过文件哈希,这意味着只存储 第一个 文件名,所有重复的文件名都将丢失。
另一种方法是直接将属性分配给哈希表:
$MD5Hashes[$_.Name] = (Get-FileHash $_.FullName -Algorithm MD5).Hash
虽然现在您不会抛出异常,但这将 覆盖 任何已经存在的项目,这意味着 last 文件有一个副本名称将被存储而其他人将丢失。
因此,我建议您使用文件的 FullName
作为哈希表的键,以确保哈希表中不会出现重复的键,并且不会丢失任何内容。