Forum Discussion
Powershell help - export to CSV not working - exporting EXE version number - help required...
One other quick explanation is the difference between Write-Host and Write-Object - which is the default pathway used when "outputting" to a device (be that file or screen):
- Write-Host writes strings to the information stream, which - put most plainly - means writing messages to the screen, not outputting data to the default stream;
- Write-Object writes an object to the standard output stream.
It's actually more complex than that but simple explanations are a good place to start.
The point is that you want to leverage writing objects to the data stream, not strings to the display.
For example, if you have the following object:
And you send that output to a CSV file, as shown below:
[PSCustomObject] @{ city = "Perth"; PostCode = 6000; } |
Export-Csv -NoTypeInformation -Path "D:\Data\Temp\Forum\forum.csv";
You get a well-formed CSV file, as we wrote an object out on the data stream (or pipeline😞
But if we write a string (via the information stream) using:
Write-Host -Object '"Perth","6000"' | Export-Csv -NoTypeInformation -Path "D:\Data\Temp\Forum\forum.csv";
You can see the output has actually gone to the screen:
And nothing has gone to the file, resulting in an empty file:
Cheers,
Lain
Morning Lain,
Can you use the same script to extract a files modified date on remote machines?
Similar to this command line (sorry I am new to PowerShell and I really appreciate your help).
Script Example (I want this 2nd script to run against a list of computers in a txt file, and output / append the created file date for a specific file to a csv file):
-----------
Script 1 :
-----------
$filePath = "C:\temp\results.txt"
$creationDate = [System.IO.File]::GetCreationTime($filePath)
Write-Output "The file was created on: $creationDate"
There is also this 2nd script which does the local machine, however I am struggling to get this to work against remote machines (40 in total).
----------
Script 2 :
-----------
$files = 'C:\path\to\first\dll','C:\path\to\second\dll' $computer = New-Object System.Object $computer | Add-Member -type NoteProperty -Name CompName -value $env:ComputerName foreach ($file in $files){ $lastWrite = Get-Item $file | select LastWriteTime $computer | Add-Member -type NoteProperty -Name $file -value $lastWrite.LastWriteTime } $computer | Export-Csv -Path "\\path\to\server\share" -Append -NoTypeInformation
- LainRobertsonJul 05, 2024Silver Contributor
Hi, Gary.
Please ensure you post sample code in a code box, as it's impossible to make sense of when it's dumped as unformatted text in the thread. This is what the second script looks like after posting:
And when that wall of text is copied-and-pasted into an IDE, it comes through as a single line, which is just as unreadable - particularly if the semicolon hasn't been used to demarcate separate commands.
Moving onto your new question, you can easily piggyback off the example scripts above.
While I'm not a fan of the SMB approach as it's slow and doesn't scale well, here's a modified SMB example that gives you the creation and modification timestamps.
For the creation and modification dates, we're simply grabbing them from the existing file object returned from Get-Item.
I've also demonstrated how you can check multiple files through pre-pending a string array in front of the Get-Item, where the relative file paths are specified as separate strings.
There's other, neater ways this can done, but by sticking as close as is possible to the original scripts above, I'm hoping it helps understand the concepts underpinning the changes, the most important being that you're working with objects.
Before getting into the example script, notice how there's multiple timestamps to choose from on the file objects returned by Get-Item? This data is what we're going to leverage.
Example
$ExportPath = "D:\Data\Temp\forum\fileInfo.csv"; Get-Content -Path "D:\Data\temp\forum\forum.txt" | ForEach-Object { $Name = $_; @( "c$\Data\SteamSetup.exe" , "c$\Data\query.txt" , "c$\Data\secedit.inf" ) | ForEach-Object { Get-Item -Path "\\$Name\$_" -ErrorAction:SilentlyContinue | ForEach-Object { [PSCustomObject] @{ Version = $_.VersionInfo.FileVersion; WhenCreated = $_.CreationTime; WhenChanged = $_.LastWriteTime; FileName = $_.VersionInfo.FileName; } } } } | Export-Csv -Path $ExportPath -NoTypeInformation;Output
Cheers,
Lain
- gower666Jul 05, 2024Copper ContributorThank you so much, worked again like a treat. Have a lovely weekend and thanks for all your help and assistance, it really is appreciated 🙂