running two powershell commandlets into a single command - powershell

I require file properties and its MD5 hash piped into a csv file, using two different commandlets for this purpose.
Can I combine both into a single command or maybe a snippet and get the desired output?
I'm using the following to get hash of the desired file aswell as file properties
Get-FileHash C:\Windows\System32\drivers\1394bus.sys Algorithm SHA512 | Format-List
Get-ChildItem C:\Windows\System32\drivers\1394bus.sys | Get-ItemProperty | Select VersionInfo | Format-List *
I'm basically new to this so any tips would be helpful!

You could reuse the Path property from the output of Get-FileHash in a calculated property, like so:
Get-FileHash C:\Windows\System32\drivers\1394bus.sys -Algorithm SHA1 |Select *,#{Label='VersionInfo';Expression={(Get-Item $_.Path).VersionInfo}} |Format-List

Related

how to filter hash in output of powershell

i am trying to make a powershell script to automatically get the hash of a file for me since i do not want to install any 3rd party applications for it
i plan to put it in the *\shell\ registry to that i can easily access it via right-click
currently i have this for sha1
[HKEY_CLASSES_ROOT\*\shell\hash\shell\01menu]
"MUIVerb"="SHA1"
[HKEY_CLASSES_ROOT\*\shell\hash\shell\01menu\command]
#="powershell -WindowStyle hidden -command get-filehash -literalpath '%1' -algorithm SHA1 | fl | clip"
my problem is that the ouput of that is
Algorithm : SHA1
Hash : AEA8544C715835248EB1A5FE782D75D6730BEA9F
Path : %PATH%\%filename%
i just want to be able to filter out the hash part so that if i run the code i will just get
AEA8544C715835248EB1A5FE782D75D6730BEA9F
without all the other stuff
how to do this?
thanks!
Or if not using .Net notation...
(A little longer and a little slower)
Get-FileHash -LiteralPath '%1' -Algorithm SHA1 | Select -ExpandProperty Hash

MD5-Checksum hashing with powershell for a whole directory

I'm trying to generate an MD5-Checksum with powershell for a whole directory.
On Linux there is a 1-liner that works just great, like this one:
$ tar -cf - somedir | md5sum
I learned that "tar" is now part of Windows10 and that it can be adressed in the PowerShell.
So I tried this:
tar -cf - C:\data | Get-FileHash -Algorithm MD5
What I get from PowerShell is this:
tar.exe: Removing leading drive letter from member names
Get-FileHash : the input object cannot be bound to any parameters of the command because the command does not accept pipeline input or the input and its properties do not match any of the parameters that accept pipeline Input
My Shell is set to german, so I ran the german error text through a Translation machine (https://www.translator.eu/#).
I wondered why I get this particular error message, because Get-FileHash IS able to process pipelined Input, e.g.:
ls | Get-FileHash -Algorithm MD5
This command just works like a charm, but it gives me checksums for each and every file.
What I want is 1 checksum for a complete given directory.
So, I probably messed up something… - any ideas?
EDIT: Here's an alternate method that is consistent even if all the files are moved/copied to another location. This one uses the hashes of all files to create a "master hash". It takes longer to run for obvious reasons but will be more reliable.
$HashString = (Get-ChildItem C:\Temp -Recurse | Get-FileHash -Algorithm MD5).Hash | Out-String
Get-FileHash -InputStream ([IO.MemoryStream]::new([char[]]$HashString))
Original, faster but less robust, method:
$HashString = Get-ChildItem C:\script\test\TestFolders -Recurse | Out-String
Get-FileHash -InputStream ([IO.MemoryStream]::new([char[]]$HashString))
could be condensed into one line if wanted, although it starts getting harder to read:
Get-FileHash -InputStream ([IO.MemoryStream]::new([char[]]"$(Get-ChildItem C:\script\test\TestFolders -Recurse|Out-String)"))
Basically it creates a memory stream with the information from Get-ChildItem and passes that to Get-FileHash.
Not sure if this is a great way of doing it, but it's one way :-)

Sort results from Get-ChildItem with Get-FileHash before output

I try to write a windows PowerShell script. I need to get file hash from all files in directory tree.
This is what I got so far:
Get-ChildItem -Path "c:\temp\path" -Recurse -Force -Attributes !Directory | % {Get-FileHash $_.Fullname} | Out-File "c:\temp\report_file.txt"
File c:\temp\report_file.txt is something like this:
Algorithm Hash Path
--------- ---- ----
SHA256 E3B0C44298...E4649B934CA495991B7852B855 c:\temp\path\report1.txt
SHA256 7B989C1C95...6756624B3887E501DCC377DB23 c:\temp\path\report2.txt
SHA256 EA0155401C...A6D44F1DEBB95E401AEFF4F908 c:\temp\path\report3.txt
SHA256 06DAA0E452...32E3F3104EA4564EAB67CA6A0A c:\temp\path\report4.txt
**SHA256 9C7C9FEA96...45F460BA9015C8F0A5CA830B6B c:\temp\path\report5.txt**
All works fine.
Expect:
I run this cmdlet a lot of times per day. Files are deleted and re-created from time to time in this directory tree. And... Several times order of files in output file is not the same.
In the example below file report5.txt in report file must be in last line, but it is on second line. I suppose it is because of recurse option is selected. This recurse option is needed for me. When I run cmdlet on directory with no subdirectories, result is equal all the time. But when on directory with subdirectories (directory tree) - not.
Algorithm Hash Path
--------- ---- ----
SHA256 E3B0C44298...E4649B934CA495991B7852B855 c:\temp\path\report1.txt
**SHA256 9C7C9FEA96...45F460BA9015C8F0A5CA830B6B c:\temp\path\report5.txt**
SHA256 7B989C1C95...6756624B3887E501DCC377DB23 c:\temp\path\report2.txt
SHA256 EA0155401C...A6D44F1DEBB95E401AEFF4F908 c:\temp\path\report3.txt
SHA256 06DAA0E452...32E3F3104EA4564EAB67CA6A0A c:\temp\path\report4.txt
Is here a solution to sort somehow all data by column fullpath before data outputed to report file?
You can sort by the path property of the hash object.
You can also run the files directly into Get-FileHash without using a loop, and I suggest exporting them to CSV instead of text, so it keeps the algorithm, hash and path separated so you can use them more easily:
Get-ChildItem -path "c:\temp\path" -Recurse -Force -File |
Get-FileHash |
Sort-Object -Property 'Path' |
Export-Csv -Path "c:\temp\report_file.csv" -NoTypeInformation

Combining MD5 Analysis with Filename in single Output

I am struggling to combine the output from two commands into a single CSV / TXT file.
The first command is to recursively search a folder and create an MD5 number for each document. This is then exported to a CSV file that includes the full path.
dir -recurse | Get-FileHash -Algorithm MD5 | Export-CSV MD5ofFolder.csv
The second command is to retrieve all the filenames within the folder (and sub-folders) WITHOUT including any pathing:
get-childitem -recurse|foreach {$_.name} > filename.txt
In a perfect world, I would be able to export a single CSV or TXT document that contains the MD5 values, the full path, and the filename (with extension).
I note that my second code string also produces the folder names in the output, which is not desirable. I am able to produce a text output without the folder names, but the code is ugly, and it doesn't do what I want:
dir -recurse | Get-FileHash -Algorithm MD5 | dir -recurse | foreach {$_.name} > filename.txt
I am sure this is a simple problem for someone smarter than me, so any and all help would be appreciated - I am VERY new to PowerShell.
Add the name to the output from Get-FileHash with Select-Object and a calculated property:
dir -recurse |Get-FileHash -Algorithm MD5 |Select-Object Hash,Path,#{Name='Name';Expression={[System.IO.Path]::GetFileName($_.Path)}} |Export-Csv filename.csv
Now you have it all in a single csv

Combine TXT files in a directory to one file with column added at end with for file name

I have got a set of txt files in a directory that I want to merge together.
The contents of all the txt files are in the same format as follows:
IPAddress Description DNSDomain
--------- ----------- ---------
{192.168.1.2} Microsoft Hyper-V Network Adapter
{192.168.1.30} Microsoft Hyper-V Network Adapter #2
I have the below code that combines all the txt files in to one txt file called all.txt.
copy *.txt all.txt
From this all.txt I can't see what lines came from what txt file. Any ideas on any bits of code that would add an extra column to the end txt file with the file name the rows come from?
As per the comments above, you've put the output of Format-Table into a text file. Note that Format-Table might be visually structured on screen, but is just lines of text. By doing that you have made it harder to work with the data.
If you just want a few properties from the results of the Get-WMIObject cmdlet, use Select-Object which (in the use given here) will effectively filter the data for just the properties you want.
Instead of writing text to a simple file, you can preserve the tabular nature of the data by writing to a structured file (i.e. CSV):
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName SERVERNAMEHERE |
Select-Object PSComputerName, IPAddress, Description, DNSDomain |
Export-Csv 'C:\temp\server.csv'
Note that we were able to include the PScomputerName property in each line of data, effectively giving you the extra column of data you wanted.
So much for getting the raw data. One way you could read in all the CSV data and write it out again might look like this:
Get-ChildItem *.csv -Exclude all.csv |
Foreach-Object {Import-Csv $_} |
Export-Csv all.csv
Note that we exclude the output file in the initial cmdlet to avoid reading and writing form/to the same file endlessly.
If you don't have the luxury to collect the data again you'll need to spool the files together. Spooling files together is done with Get-Content, something like this:
Get-ChildItem *.txt -Exclude all.txt |
Foreach-Object {Get-Content $_ -Raw} |
Out-File all.txt
In your case, you wanted to suffix each line, which tricker as you need to process the files line-by-line:
$files = Get-ChildItem *.txt
foreach($file in $files) {
$lines = Get-Content $file
foreach($line in $lines) {
"$line $($file.Name)" | Out-File all.txt -Append
}
}