Strange format of a table in a txt file - powershell

In a powershell script, I am creating a txt file:
#Create a logfile
$logfile = "E:\scripts\Password expiration\PasswordExpiryLog.txt"
#Initialize the log file with the date
$date = Get-Date -Format "dd.MM.yyyy HH:mm:ss"
$message= "********************" + $date + "********************"
Add-Content $logfile $message
After that, I do some other things to get some info. When I try to send that info into the TXT file, formatting the info as a table, it writes the information in a way that the information is not in columns, missing the break of line. I mean, if I press enter where the next line should start, it is written in a column.
$Expired | FORMAT-TABLE #{Name='UserPrincipalName';Expression={"$($_.UserPrincipalName)"};align ='left'}, #{Name='rapasswordexpiring';Expression={"$($_.rapasswordexpiring)"};align ='center'}, #{Name='PasswordLastSet';Expression={"$($_.PasswordLastSet)"};align ='left'} -AutoSize | Out-File -Append 'E:\scripts\Password expiration\PasswordExpiryLog.txt'
I have also realized, while writing this message, that between the characters there is always a space
How it looks
How it should look
If I instead of out-file to the same logfile I use a new txt file, the information is written correctly.
$Expired | FORMAT-TABLE #{Name='UserPrincipalName';Expression={"$($_.UserPrincipalName)"};align ='left'}, #{Name='rapasswordexpiring';Expression={"$($_.rapasswordexpiring)"};align ='center'}, #{Name='PasswordLastSet';Expression={"$($_.PasswordLastSet)"};align ='left'} -AutoSize | Out-File -Append 'E:\scripts\Password expiration\table.txt'
Correct
However, I cannot get here the date and time.
Can you tell me what am I doing wrong or how to improve the output? I would be able to use cvs or html file if would be better.

Different default encoding:
Add-Content:
-Encoding Specifies the type of encoding for the target file. The
default value is Default.
Default Uses the encoding that corresponds to the system's active
code page (usually ANSI).
Out-File
-Encoding Specifies the type of encoding for the target file. The
default value is unicode.
unicode Uses UTF-16 with the little-endian byte order.

Related

Why am I getting gibberish when outputting to a text file from powershell?

I am trying to output all the file names in a directory to a file. Seems simple, but in the future I will be creating useful information based off the file names and outputting to a file for another system.
When I output the information to a file it shows as gibberish when I open in notepad. Outputting to the screen looks fine.
Here is my code:
$files = Get-ChildItem "s:\centmobile\rates\currentrates\forupload\"
$outfile = "s:\centmobile\rates\currentrates\test.txt"
"New File"|Out-File $outfile -Encoding ascii
foreach ($f in $files){
Get-Content $f.FullName | Add-Content $outfile -Encoding Ascii
Write-Output $f.FullName
}
Screen output looks good:
PS C:\Windows\System32\WindowsPowerShell\v1.0> S:\CentMobile\Software\Dev\cre8hdrinfo.ps1
S:\centmobile\rates\currentrates\forupload\2019406BICS_BC_Rates_ForUpload.xlsx
S:\centmobile\rates\currentrates\forupload\2019406BICS_FC_Rates_ForUpload.xlsx
File output looks not so good..
New File
PK ! –~íGq % [Content_Types].xml ¢(  ¬”ËNÃ0E÷HüCä-Jܲ#5í‚Ç
A%ʘxÒXqlËã–öU(4BÍ&–ã™{O&3žÌ6NÖàQY“³q6b ˜ÂJe–9û\¼¤÷,Á ŒÚÈÙͦ×W“ÅÖ&”m0gUîs,*hfÖ¡“ÒúFÚú%w¢¨ÅøíhtÇk˜†VƒM'OPŠ•Éó†^ïH<hdÉã.°õÊ™pN«B"åk#¹¤{‡Œ2cVÊá
a0ÞéОüm°Ï{§Òx%!™ÞDC|£ù·õõ—µuv^¤ƒÒ–¥*#ÚbÕP2t„Ä
4:‹kÖeÜgüc0ò¸Œi¿/
÷p ý0o„~U¦F~ºšèT»*PÏË)¢L!†­º¢hŸs%<Èài\8Õ>ÇAÍ<÷Ö!µ‡ÿWá0·mvêH|PpœÜ® 8:Ò•pqÙÛÎ2d‡7—Üô ÿÿ PK ! µU0#ô L _rels/.rels ¢(  ¬’MOÃ0†ïHü‡È÷ÕÝBKwAH»!T~€Iܵ£$Ý¿'TƒG½~üÊÛÝ<êÈ!öâ4¬‹;#¶w­†—úqu*&r–Fq¬áÄvÕõÕö™GJy(v½*«¸¨¡KÉß#FÓñD±Ï.W ¥†=™ZÆMYÞbø®ÕBSí­†°·7 ê“Ï›×–¦é
?ˆ9LìÒ™ÈsbgÙ®|Èl!õùUSh9i°bžr:"y_dlÀóD›¿ý|-NœÈR"4ø2ÏGÇ% õZ´4ñËyÄ7 ëÈðÉ‚‹¨Þ ÿÿ PK ! …ë — † xl/workbook.xml¬Umo›:þ~¥ýÆýLÁ¼ƒ’LI ÝJÛT¥]÷¥Òä€S¬æÓ¤ªößwlBš.ÕÔu‹ˆß?çœç&vu¥ÝÞQÖLutféirVÐævª¹ÊŒP×:›W¬!Sýtú‡Ù»&[ÆïÖŒÝi ÐtS½¢M³ËKRã¤•
ã50ä·f×r‚‹®$DÔ•i[–oÖ˜6ú€ó×`°Í†æ$ay_“F œTX ý®¤m7¢ÕùkàjÌïúÖÈYÝÄšVT<(P]«óøü¶a¯+0{‡<mÇáñá,hìñ&X:¹ª¦9gÛˆ3€6Ò'ö#ËDè™v§>x’krrOe¬¸ÿFVþËCÖ£!–ÒJÎ{#šwàfë³É†Väz®†Ûö3®e¤*]«p'Ò‚
RLõ †lKžMð¾]ô´‚U¹¶§›³ƒœ/¸V
...
The reason your screen output and file looks very different is that you're not outputting the same content at all to screen and file.
With:
Get-Content $f.FullName | Add-Content $outfile -Encoding Ascii
you are, as the command implies, getting the content of every file and outputting to $outfile.
While with:
>Write-Output $f.FullName
You are just outputting the list of file names to screen.
As your question says it's the filenames you're after, just change:
Get-Content $f.FullName | Add-Content $outfile -Encoding Ascii
to:
$f.FullName | Add-Content $outfile -Encoding Ascii
and it should output the same thing to screen as to the file.
A good way to check/troubleshoot here would've been to just remove everything after:
Get-Content $f.FullName
and look at the output, which will look very similar to the file and give you a hint that something's wrong there.
Get-Content cmdlet returns strings or bytes (strings in your case). The gibberish you are getting comes from interpretation binary values from xlsx files as Ascii strings (unsolvable mojibake case).
Resources (required reading, incomplete):
From fileformatcommons.com:
xlsx files are actually zip files in disguise…
xlsx file character encoding / charset is binary
From .ZIP File Format Specification
local file header signature (4 bytes) 0x04034b50
From Zip (file format) at Wikipedia:
Most of the signatures end with the short integer 0x4b50, which is
stored in little-endian ordering. Viewed as an ASCII string this reads
"PK", the initials of the inventor Phil Katz. Thus, when a ZIP file is
viewed in a text editor the first two bytes of the file are usually
"PK".

Out-File -append in Powershell does not produce a new line and breaks string into characters

I'm trying to understand some weird behaviour with this cmdlet.
If I use "Out-File -append Filename.txt" on a text file that I created and entered text into via the windows context menu, the string will append to the last line in that file as a series of space separated characters.
So:
"This is a test" | out-file -append textfile.txt
Will produce:
T h i s i s a t e s t
This wont happen if out-file creates the file, or if the text file has no text in it prior to appending. Why does this happen?
I will also note that repeating the command will just append in the same way to the same line. I guess it doesn't recognise newline or line break terminator or something due to changed encoding?
Out-File defaults to unicode encoding which is why you are seeing the behavior you are. Use -Encoding Ascii to change this behavior. In your case
Out-File -Encoding Ascii -append textfile.txt.
Add-Content uses Ascii and also appends by default.
"This is a test" | Add-Content textfile.txt.
As for the lack of newline: You did not send a newline so it will not write one to file.
Add-Content is default ASCII and add new line however Add-Content brings locked files issues too.

Powershell Add-content Out-File Text is wrong

When i use this:
"$LogTime $CurrentDate Invalid Archive Grouping selected. You selected '$ArchiveGrouping'" | Out-File $LogFile -Append -Force
To write to a file i generated with this code:
$Logdate = Get-Date
$Logname = $Logdate.ToString("yyyyMMdd") + ".txt"
Add-Content -Path C:\ArchiveStorage\$Logname "Log" -force
$LogFile = "C:\ArchiveStorage\$Logname"
The Text in the file looks weird it looks like this:
if i change the code to just write to an existing file like:
$LogFile = "C:\ArchiveStorage\Log.txt"
The text file is as it should be:
why does it make spaces and all that random crap ?
You've been hit by double byte Unicode. When, say, letter A is written into the file, there usually is a single byte value 0x41. In double byte Unicode, the byte value for A is 0x0041 or 0x4100 depending on endianess.
When Notepad opens a file that has no Unicode byte order mark, it assumes all the extra 00 in file contents are blank spaces. That's why you do see w e r i d s p a c i n g.
For a fix, try using -Encoding ASCII parameter with Add-Content.
The "Log" entries look different because they were written with Add-Content, which uses a default encoding of ASCII, and Out-File uses a default encoding of Unicode.
Either specify the encoding type on Out-File, or switch to using Add-Content for both the "Log" heading and the detail lines.

Powershell Out-File Doesn't Work For CSV

I have the following code:
$databaseContents = "col1,col2,col3,col4"
$theDatabaseFile = "C:\NewFolder\Database.csv
$databaseContents | Out-File $theDatabaseFile
However when I open the csv file in Excel, it has col1,col2,col3,col4 in cell A1 rather than col1 in cell A1, col2 in cell B1 etc.
Something strange I've noticed:
If I open the file in Notepad and copy the text into another Notepad instance and save it as Database1.csv, then open it in Excel, it displays as expected.
How can I get the Out-File commandlet to save it as a .csv file with the contents in 4 columns as expected?
EDIT:
I've noticed if I use Set-Content rather than Out-File, the csv file is then displayed correctly in Excel.
Does anyone know why this is?
Why it makes a difference to Excel I am unclear, but it comes down to the encoding of the resulting output file - Unicode (in the cases that do not work) vs. ASCII (in the cases that do).
#JPBlanc's alternate approach works because it sets the encoding of the output file to ASCII where your original example (implicitly) set the encoding of the output file to Unicode.
Just adding -Encoding ascii to your original example works fine too:
$databaseContents = "col1,col2,col3,col4"
$theDatabaseFile = "C:\NewFolder\Database.csv
$databaseContents | Out-File $theDatabaseFile -Encoding ascii
And adding an explicit -Encoding unicode to your original example yields the same broken result you encountered:
$databaseContents = "col1,col2,col3,col4"
$theDatabaseFile = "C:\NewFolder\Database.csv
$databaseContents | Out-File $theDatabaseFile -Encoding unicode
This is basically what was happening implicitly.
This works also :
$databaseContents = "col1;col2;col3;col4"
$theDatabaseFile = "C:\temp\Database.csv"
$databaseContents | Out-File $theDatabaseFile -Encoding ascii
By default CSV separator in Excel seams to be ';' and Out-File save as unicode forcing ASCII seams to give the result you look for.
I was having the same problem than Backwards_Dave and just like him, using the Set-Content instead of Out-File command worked for me:
#Build $temp String
$temp = "$scriptApplication;$applicationName;$type;$description;$maxSessions;$enabled;$tempParams`n"
#Write $temp String to $fichierCsv file
"$temp" | Set-Content $fichierCsv
I tried using JPBlanc's and J0e3gan's solution but it did not work (-Encoding ascii option): I wonder why.

Powershell file output twice the size

Background
I have a pipe delimited csv file that looks like this:
ColA|ColB|ColC|ColD|ColE|ColF|ColG|ColH|ColI|ColJ|ColK
00000000|000000507|0000000|STATUS|0000|000000|000|0000|00|0000|00000
00000000|000000500|0000000|STATUS|0000|000000|000|0000|00|0000|00000
00000000|000007077|0000000|STATUS|0000|000000|000|0000|00|0000|00000
I want to take ColB on lines with a certain status and put it in a headless csv file like this:
000000507,0000000001,0,0
000000500,0000000001,0,0
000007077,0000000001,0,0
The values 0000000001,0,0 on the end of the line are identical for every item.
The Script
The trimmed down/generic version of the script looks like this:
$infile = Import-Csv ".\incsv.txt" -Delimiter '|'
$outfile = ".\outcsv.txt"
Foreach($inline in $infile){
If($inline.Status -ne 'Some Status'){
$outline = $inline.'ColB' + ',0000000001,0,0'
Add-Content $outfile $outline -Encoding ASCII
}
}
The Problem
The problem is that the new file that is created is about twice the size it should be, and I know it has to do with the encoding. Unfortunately, I can't find an encoding that works. I've tried -Encoding ASCII, -Encoding Default, -Encoding UTF8, but they all are too large.
This wouldn't be an issue, but the program that reads the created text file won't read it correctly.
What I can do, is copy the text from the new file in Notepad, save it as ANSI, and it works fine. ANSI isn't an option in the -Encoding parameter though.
How do I get Powershell to output the correct file type? Is there a better way to approach this?
I've found this Google Groups conversation and this Social TechNet post, but neither one actually worked for me.
If the output file already exists and is in Unicode format the parameter -Encoding ASCII is ignored when appending to the file. Change your loop to this:
$infile | % {
if ($_.Status -ne 'Some Status') {
$_.'ColB' + ',0000000001,0,0'
}
} | Set-Content $outfile -Encoding ASCII