Upload JES job using Powershell and FTP and download the response - powershell

I'm using this script to upload a JOB on the Mainframe.
"open $FTPserver" | Out-File ftp.scr -Encoding ASCII
$FTPusername | Out-File ftp.scr -Encoding ASCII -Append
$FTPpassword | Out-File ftp.scr -Encoding ASCII -Append
"quote site filetype=jes" | Out-File ftp.scr -Encoding ASCII -Append
"put " + $FTPfile | Out-File ftp.scr -Encoding ASCII -Append
"quit" | Out-File ftp.scr -Encoding ASCII -Append
ftp.exe -s:ftp.scr
Remove-Item ftp.scr
Script works great. But I would like to save this response to variable so I can download in the next step this JOB for the response. This is my targeted response:
250-It is known to JES as JOB24503
Is there a way also to hide the output text from the FTP?

To redirect output to a file use the > operator.
ftp.exe -s:ftp.scr > ftp.out
I'm not a powershell guru but I do know that you can use the full .NET API which gives you access to a very sophiticated runtime. Check out FtpWebRequest which can be used to run FTP requests and pipe the output back to streams.

Related

ASCII encoding does not work in powershell

Just can't get ASCII encoding get to work in PowerShell. Tried a bunch of different approaches.
Whatever I try I get an UTF8 encoded file (that is what NPP tells me):
$newLine = "Ein Test öäü"
$newLine | Out-File -FilePath "c:\temp\check.txt" -Encoding ascii
PSVersion = 5.1.14393.5066
Any hint is welcome!
ASCII is a 7-bit character set and doesn't contain any accented character, so obviously storing öäü in ASCII doesn't work. If you need UTF-8 then you need to specify encoding as utf8
$newLine = "Ein Test öäü"
$newLine | Out-File -FilePath "c:\temp\check.txt" -Encoding utf8
If you need another encoding then specify it accordingly. For example to get the ANSI code page use this
$newLine = "Ein Test öäü"
$newLine | Out-File -FilePath "c:\temp\check.txt" -Encoding default
-Encoding default will save the file in the current ANSI code page and -Encoding oem will use the current OEM code page. Just press Tab after -Encoding and PowerShell will cycle through the list of supported encodings. For encodings not in that list you can trivially deal with them using System.Text.Encoding
Note that "ANSI code page" is a misnomer and the actual encoding changes depending on each environment so it won't be reliable. For example if you change the code page manually then it won't work anymore. For a more reliable behavior you need to explicitly specify the encoding (typically Windows-1252 for Western European languages). In older PowerShell use
[IO.File]::WriteAllLines("c:\temp\check.txt", $newLine, [Text.Encoding]::GetEncoding(1252)
and in PowerShell Core you can use
$newLine | Out-File -FilePath "check2.txt" -Encoding ([Text.Encoding]::GetEncoding(1252))
See How do I change my Powershell script so that it writes out-file in ANSI - Windows-1252 encoding?
Found the solution:
$file = "c:\temp\check-ansi.txt"
$newLine = "Ein Test öÖäÄüÜ"
Remove-Item $file
[IO.File]::WriteAllLines($file, $newLine, [Text.Encoding]::GetEncoding(28591))

Powershell 7 - Set-Content and Out-file adds a Carriage Return (CR) to my file

I am manipulating a file with the Get-Content command, doing a replace then piping it to Set-Content or Out-File. But the the file gets written with a CR before all my linefeeds. My original file has linefeeds, which is OK, but the CR breaks the file for what its being used for.
I tried this Powershell replace content in file adds redundent carriage return
But cannot get it to work. And I would like to avoid using .NET if possible
Here is my code:
(Get-Content "FILE.TEMPLATE") -replace('SEQUENCE', "$NEWSEQUENCE") | Set-Content ("FILE.NEW")
or
(Get-Content "FILE.TEMPLATE") -replace('SEQUENCE', "$NEWSEQUENCE") | Set-Content ("FILE.NEW") -Encoding UTF8NoBOM
I tried setting the encoding with '-Encoding' after the Set-Content pipe, but that does nothing. Tried UTF8, UTF8NoBOM. This out put file is destined to be used to on a UNIX box, which is why the CR breaks the file.
Any ideas?
It took some more digging around and here is what worked
(Get-Content "FILE.TEMPLATE" -Raw) -replace 'SEQUENCE', "$NEWSEQUENCE" |
Set-Content "FILE.NEW" -NoNewLine -Encoding UTF8NoBOM
Had to add -Raw to Get-Content, then add -NoNewLine and -Encoding UTF8NoBOM to Set-Content.
This will only work with PowerShell 6+, since anything below does not have UTF8NoBOM as an encoding option. Powershell 5 defaults to UTF8BOM.

Modify a JSON file with PowerShell without writing BOM

I need to modify an existing UTF8 encoded JSON file with PowerShell. I tried with the following code:
$fileContent = ConvertFrom-Json "$(Get-Content $filePath -Encoding UTF8)"
$fileContent.someProperty = "someValue"
$fileContent | ConvertTo-Json -Depth 999 | Out-File $filePath
This adds a BOM to the file and also encodes it in UTF16. Is it possible to have ConvertFrom-Json and ConvertTo-Json do not do the encoding / BOM?
This has nothing to do with ConvertTo-Json or ConvertFrom-Json. The encoding is defined by the output cmdlet. Out-File defaults to Unicode, Set-Content to ASCII. With each of them the desired encoding can be defined explicitly:
... | Out-File $filePath -Encoding UTF8
or
... | Set-Content $filePath -Encoding UTF8
That will still write a (UTF8) BOM to the output file, but I wouldn't consider UTF-8 encoding without BOM a good practice anyway.
If you want ASCII-encoded output files (no BOM) replace UTF8 with Ascii:
... | Out-File $filePath -Encoding Ascii
or
... | Set-Content $filePath # Ascii is default encoding for Set-Content

tee with utf-8 encoding

I'm trying to tee a server's output to both the console and a file in Powershell 4. The file is ending up with a UTF-16 encoding, which is incompatible with some other tools I'm using. According to help tee -full:
Tee-Object uses Unicode enocding when it writes to files.
...
To specify the encoding, use the Out-File cmdlet
So tee doesn't support changing encoding, and the help for both tee and Out-File don't show any examples of splitting a stream and encoding it with UTF-8.
Is there a simple way in Powershell 4 to tee (or otherwise split a stream) to a file with UTF-8 encoding?
One option is to use Add-Content or Set-Content instead of Out-File.
The *-Content cmdlets use ASCII encoding by default, and have a -Passthru switch so you can write to the file, and then have the input pass through to the console:
Get-Childitem -Name | Set-Content file.txt -Passthru
You would have to use -Variable and then write it out to a file in a separate step.
$data = $null
Get-Process | Tee-Object -Variable data
$data | Out-File -Path $path -Encoding Utf8
At first glance it seems like it's easier to avoid tee altogether and just capture the output in a variable, then write it to the screen and to a file.
But because of the way the pipeline works, this method allows for a long running pipeline to display data on screen as it goes along. Unfortunately the same cannot be said for the file, which won't be written until afterwards.
Doing Both
An alternative is to roll your own tee so to speak:
[String]::Empty | Out-File -Path $path # initialize the file since we're appending later
Get-Process | ForEach-Object {
$_ | Out-File $path -Append -Encoding Utf
$_
}
That will write to the file and back to the pipeline, and it will happen as it goes along. It's probably quite slow though.
Tee-object seems to invoke out-file, so this will make tee output utf8:
$PSDefaultParameterValues = #{'Out-File:Encoding' = 'utf8'}
First create the file using appropriate flags then append to it:
Set-Content out $null -Encoding Unicode
...
cmd1 | tee out -Append
...
cmdn | tee out -Append

Powershell logging from Invoke-Expression with encoding

I have an specific scenario where I have to log a batch file using Invoke-Expression in Powershell but my logs are being saved with "UCS-2 Little Endian" Encoding and I would like to save it with UTF-8 or any other encoding.
This is a simple example of what I'm trying to do:
batch file (test.bat):
echo Test
Powershell file (test.ps1):
Invoke-Expression "c:\test.bat > log.txt"
Is there a way I could change the encoding on log.txt?
You can try this:
C:\test.bat | Out-File C:\log.txt -Encoding UTF8
Or if for whatever reason you really have to use Invoke-Expression:
Invoke-Expression "C:\test.bat" | Out-File C:\log.txt -Encoding UTF8
Note that this will overwrite log.txt everytime. If you want to append to the file do this:
Invoke-Expression "C:\test.bat" | Out-File C:\log.txt -Encoding UTF8 -append
or
Invoke-Expression "C:\test.bat" | Add-Content C:\log.txt -Encoding UTF8