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 作为哈希表的键,以确保哈希表中不会出现重复的键,并且不会丢失任何内容。