Einen Hash über Powershell erstellen für mehrere Dateien
Hey an Alle,
Ich habe zurzeit die Aufgabe, aus Archivierungsgründen eine Hash über meine Powerschell zu erstellen, die alle Dateien in einem Ordner in insgesamt einer Prüfsumme sammelt. Ich habe bisschen gegoogelt, gefunden habe ich bis jetzt nur wie ich mit "Get-FileHash" eine Hash für jeweils eine Datei erzeuge. Es bringt mir leider auch nichts, nur die Prüfsumme von dem Ordner zu erstellen, es sollen am besten alle Dateien in diesem Ordner gelistet sein, da mir gesagt wurde, dass die Prüfsumme nicht mehr stimmen wird beim Vergleich. Gibt es einen Befehl, wo ich, vielleicht mit Get-FileHash, alle Dateien aufliste und die Shell mir dann eine einzige Hash erzeugt?
Liebe Grüße,
Robin
Ich habe zurzeit die Aufgabe, aus Archivierungsgründen eine Hash über meine Powerschell zu erstellen, die alle Dateien in einem Ordner in insgesamt einer Prüfsumme sammelt. Ich habe bisschen gegoogelt, gefunden habe ich bis jetzt nur wie ich mit "Get-FileHash" eine Hash für jeweils eine Datei erzeuge. Es bringt mir leider auch nichts, nur die Prüfsumme von dem Ordner zu erstellen, es sollen am besten alle Dateien in diesem Ordner gelistet sein, da mir gesagt wurde, dass die Prüfsumme nicht mehr stimmen wird beim Vergleich. Gibt es einen Befehl, wo ich, vielleicht mit Get-FileHash, alle Dateien aufliste und die Shell mir dann eine einzige Hash erzeugt?
Liebe Grüße,
Robin
Please also mark the comments that contributed to the solution of the article
Content-Key: 7029464841
Url: https://administrator.de/contentid/7029464841
Printed on: May 23, 2024 at 21:05 o'clock
12 Comments
Latest comment
Moin,
du solltest dir unbedingt mal die Beschreibung von Get-FileHash ansehen. Ganz wichtig dabei ist die Informationen wovon eigentlich ein Hash erstellt wird.
du solltest dir unbedingt mal die Beschreibung von Get-FileHash ansehen. Ganz wichtig dabei ist die Informationen wovon eigentlich ein Hash erstellt wird.
$allhashes = (Get-ChildItem "E:\Ordner" -File -Recurse | Get-FileHash -Algorithm SHA256).Hash -join ''
$folderHash = [System.BitConverter]::ToString([System.Security.Cryptography.HashAlgorithm]::Create("SHA256").ComputeHash([System.Text.Encoding]::ASCII.GetBytes($allhashes))).replace('-','')
Gruß pille
Zitat von @DerWoWusste:
7zip macht das ordentlich:
7zip macht das ordentlich:
"c:\Program Files\7-Zip\7z.exe" h -scrcsha256 "c:\ordner"
man könnte auch die Ausgabe von
Get-FileHash c:\temp\*
ein eine Datei schreiben
$folder = "D:\tmp\"
$tempFile = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
Get-ChildItem -Recurse -File $folder | Get-FileHash | Select-Object Hash | Set-Content $tempFile
$folderHash = Get-FileHash $tempFile
Remove-Item $tempFile -Force
-Thomas
Zitat von @3063370895:
oder$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write((Get-FileHash c:\temp\*))
$writer.Flush()
$stringAsStream.Position = 0
Get-FileHash -InputStream $stringAsStream | Select-Object Hash
bleibt aber immer noch die Frage offen, welche Intigrität eigentlich wie geprüft werden soll...
Schnellere Hashes würde auch ein CRC32 Hash liefern, gerade bei großen Dateien spart das einiges an Zeit, das reicht manchmal schon.
Add-Type '
using System;
using System.IO;
public static class CRC32{
public static string ComputeHash(Stream stream){
uint[] ChecksumTable = new uint[0x100];
uint poly = 0xEDB88320;
for (uint index = 0; index < 0x100; ++index){
uint item = index;
for (int bit = 0; bit < 8; ++bit)
item = ((item & 1) != 0) ? (poly ^ (item >> 1)) : (item >> 1);
ChecksumTable[index] = item;
}
uint result = 0xFFFFFFFF;
int current;
while ((current = stream.ReadByte()) != -1)
result = ChecksumTable[(result & 0xFF) ^ (byte)current] ^ (result >> 8);
byte[] hash = BitConverter.GetBytes(~result);
Array.Reverse(hash);
return BitConverter.ToString(hash).Replace("-","");
}
public static string ComputeHash(byte[] data){
using (MemoryStream stream = new MemoryStream(data))
return ComputeHash(stream);
}
public static string ComputeHash (string file){
using (FileStream stream = new FileStream(file,FileMode.Open))
return ComputeHash(stream);
}
}'
$hashes = foreach($file in Get-ChildItem "E:\Ordner" -File -Recurse){[CRC32]::ComputeHash($file.Fullname)}
$folderHash = [System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::ASCII.GetBytes($hashes))).replace('-','')
Zitat von @pille6:
Schnellere Hashes würde auch ein CRC32 Hash liefern, gerade bei großen Dateien spart das einiges an Zeit, das reicht manchmal schon.
Ist bei mir um Faktor 5 langsamer als Get-FilehashSchnellere Hashes würde auch ein CRC32 Hash liefern, gerade bei großen Dateien spart das einiges an Zeit, das reicht manchmal schon.
-Thomas
Zitat von @3063370895:
Ist bei mir um Faktor 5 langsamer als Get-Filehash
Wiederhol das mal mit größeren Dateien und SHA256 Dann wirst du den Unterschied sehen ...Ist bei mir um Faktor 5 langsamer als Get-Filehash
Hier ein Vergleich beider Methoden eines Verzeichnisses rekursiv mit 2000 Dateien im RAM, erste Zeit CRC32, zweite Zeit Get-FileHash
CRC32 = 1,1185974s
Get-FileHash = 2,629939s
Hier über einen 1,3 GB Ordner mit Videos:
Hier mit PS 5.1, damit keiner sagt es liegt an PS7
Nicht ganz Faktor 5, aber 3-4
Hier der ganze Code:
Ach nochwas: Ich glaube nicht, dass OP die selbe Datei im RAM 2000 mal hashen will
-Thomas
Hier mit PS 5.1, damit keiner sagt es liegt an PS7
Nicht ganz Faktor 5, aber 3-4
Hier der ganze Code:
$folder = "D:\tmp"
$sha256 = Measure-Command -Expression {
$tempFile = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
Get-ChildItem -Recurse -File $folder | Get-FileHash -Algorithm SHA256| Select-Object Hash | Set-Content $tempFile
$folderHashsha256 = Get-FileHash -Algorithm SHA256 $tempFile
remove-item $tempFile -force
} | select -expandproperty totalseconds
$crc32 = Measure-Command -Expression {
Add-Type '
using System;
using System.IO;
public static class CRC32{
public static string ComputeHash(Stream stream){
uint[] ChecksumTable = new uint[0x100];
uint poly = 0xEDB88320;
for (uint index = 0; index < 0x100; ++index){
uint item = index;
for (int bit = 0; bit < 8; ++bit)
item = ((item & 1) != 0) ? (poly ^ (item >> 1)) : (item >> 1);
ChecksumTable[index] = item;
}
uint result = 0xFFFFFFFF;
int current;
while ((current = stream.ReadByte()) != -1)
result = ChecksumTable[(result & 0xFF) ^ (byte)current] ^ (result >> 8);
byte[] hash = BitConverter.GetBytes(~result);
Array.Reverse(hash);
return BitConverter.ToString(hash).Replace("-","");
}
public static string ComputeHash(byte[] data){
using (MemoryStream stream = new MemoryStream(data))
return ComputeHash(stream);
}
public static string ComputeHash (string file){
using (FileStream stream = new FileStream(file,FileMode.Open))
return ComputeHash(stream);
}
}'
$hashes = foreach ($file in Get-ChildItem $folder -File -Recurse) { [CRC32]::ComputeHash($file.Fullname) }
$folderHashcrc32 = [System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::ASCII.GetBytes($hashes))).replace('-', '')
} | select -expandproperty totalseconds
[PSCustomObject]@{
"SHA256Time" = $sha256
"CRC32Time" = $crc32
}
Ach nochwas: Ich glaube nicht, dass OP die selbe Datei im RAM 2000 mal hashen will
-Thomas