Running executables in Powershell with complex arguments - powershell

I am working on converting an old massive batch file logging script to Powershell. Creating the data has not been a major issue, but I am having an issue with the final step. The final step in the old batch file converts an ugly CSV into a more pretty and easy-on-the-eyes CSV. This is done using an old AWK script and a gawk command. I am content leaving that step in place, but I want it to be executed from within the Powershell script.
The command looks something like this:
<gawk.exe> -f <path>\PrepareReport.awk <original.csv> >> <final.csv>
I have tried different ways of calling gawk and the arguments. Invoke-Expression, Invoke-Command, etc. Nothing seems to work to run this command properly. Any insight or ideas would be appreciated.
Thanks!
EDIT: Following all the comments, I have found the & is the option that works to make this happen. The Start-Process cmdlet causes a fatal error. One weird thing is still happening though. For some reason the resulting CSV file does not display normally in Excel. Even though the resulting file seems to be perfectly normal, Excel won't display it using the appropriate comma breaks. Any thoughts?

You could always use Start-Process.
Start-Process -NoNewWindow -Wait -PassThru -FilePath <gawk.exe> -ArgumentList "-f <path>\PrepareReport.awk <original.csv> >> <final.csv>"
It's a little wordy, but very customisable and very flexible.

Related

2goarray works in cmd but not powershell

I am trying to use 2goarray to write a .ico file to a go file so that I can use it in systray.
My problem is that this works in cmd:
TYPE icon.ico | 2goarray Data icon > icon.go
But running the equivalent command in powershell does not:
Get-Content .\icon.ico | 2goarray Data icon | Out-File -FilePath .\icon.go -Encoding UTF8
When I say it doesn't work, I don't mean an error occurs, I mean that the array produced by 2goarray is not correct, it contains data that systray doesn't recognize as an icon.
For reference, here is the working icon.go, here is the broken/corrupted one produced by powershell, and here is the icon I am using.
I suspect it has something to do with the way that powershell passes things as objects, but I'm not sure?
Your challenge is to pipe binary data in PowerShell, which is not that straight forward. I tested your example with this command and I get the "working" icon.go:
Start-Process 2goarray -ArgumentList "Data icon" -RedirectStandardInput .\icon.ico -RedirectStandardOutput .\icon.go
But this solution seems to be quite slow compared to cmd. From PowerShell you can also always call cmd if you want to, which works surprisingly faster for your example:
Start-Process cmd -ArgumentList "/c TYPE icon.ico | 2goarray Data icon > icon.go"
Often, it is a bad design to call cmd from PowerShell, because PowerShell can nearly do everything that cmd can do, and often more, but for your example, this seems to be the better solution.

Powershell not executing from CMD (Batch) script

There are quite some questions asked already regarding this issue, but none of the answers resolved mine.
I wrote following batch script:
powershell.exe -executionpolicy bypass -file "./myps.ps1"
I saved the file as autorun.cmd
Whenever I double-click the cmd file, nothing happens, CLI quickly shows up and closes but powershell was not executed.
If I run the same command directly in CLI, it works.
I am really confused on what's going on here. Any help would be appreciated.
Saving it as a .bat extension will fix it. Like you, I was never able to get a .cmd file to work as a batch file as well.
So, hi and welcome to this platform...
I try run this powershel code above, that convert ansi to unicode file, by bat file using your command inside the bat:
Set-Location ".\"
Get-Content 'ansi.txt' | Set-Content -Encoding unicode 'outunicode.txt'
And all running fine, my bat call to execute .ps1 code (copied from you to test propose), above the code inside bat file, like your code:
powershell.exe -executionpolicy bypass -file "./myps.ps1"
All run OK, no error, and the result file OK too!
So, this make me suggest to you, that maybe you need try running the bat file direct in your command line for to be able to see possible error message, and filling if this is a bat/powershell/security/other error, and, if possible, post/share the content .ps1 file, I'm 100% sure, that here are someone (a lot of them) will be capable help you precisely and quickly. Sorry my English.

Run Powershell script from inside other Powershell script with dynamic redirection to file

I have been struggling with this problem and researching around but can't get a solution
My problem: I need to run a Powershell script from inside another Powershell script and redirect the output stream to a file. So far so good.
The real issue comes when I need to control the amount of logging through a variable (e.g. write only errors or only error + warning + success output streams).
I can get around it by hard-coding the command as in:
Powershell -File "\path\myscript.ps1" 2>&1> $logFilePathAndName
However, I want to give the user a couple of options for the redirect operator and want to avoid hardcoding each one of them. For that, I was thinking to just code something similar to :
$logStreams = "2>&1>"
Powershell -File "\path\myscript.ps1" $logStreams $logFilePathAndName
The last command does run my script (myscript.ps1 has no input params) but it does not write anything to the file at $logFilePathAndName.
I tried various syntax with Invoke-Command, Invoke-Expression, the call operator and Powershell -Command with no luck.
Looked at this post, had several tries but I can't just get it to work.
For example this runs my script but does not write anything to the output log:
$logStreams = "2>&1>"
$command = '"C:\myscript.ps1" $_logStreams "C:\outputlog.txt"'
iex "& $command"
Is there a way to pass a variable string for the redirect operator OR run a string containing the entire command with a variable interpolated for the output redirector ?
Your last bit there is very close, but I'm not sure why you have the underscore in there, and you need to escape your dollar sign, and close the entire thing in double quotes to cause string extrapolation.
$logStreams = "2>&1>"
$command = "'C:\myscript.ps1' $logStreams 'C:\outputlog.txt'"
iex "& $command"
I just tested that locally and it works fine.

Get-Content with wait parameter doesn't update in Powershell

I'm trying to monitor a file using Get-Content $path -wait in Windows Powershell V3.0. Sometimes when I execute this command line in Powershell it will function as expected. But sometimes it will only execute (or at least it seems like) get-content but without the -wait parameter. Even though the file get's updated it won't be shown in Powershell. If I cancel the command and rerun it it will show the updated file content.
What do I need to do?
EDIT: It seems to update blocks after a while. But it's not real-time really.
Not allowed to comment (don't have a 50 reputation), so have to give an Answer....
Less for Windows (http://gnuwin32.sourceforge.net/packages/less.htm) with the +F or Shift-F option (http://www.commandlinefu.com/commands/view/1024/make-less-behave-like-tail-f.) showed updated file content where PowerShell "get-content $path -wait" did not.

Powershell 2: Easy way to direct every bit of output to a file?

I have a script that generates output of various forms - mostly standard output and error channels.
I have tried things like:
script.ps1 > $somefile 2>&1
script.ps1 | tee-object <args>
script.ps1 | out-file <args>
I've also tried start-transcript / stop-transcript. All of these methodologies have their drawbacks, or just don't plain seem to work.
What is the closest powershell equivalent of the UNIX-style invocation:
myScript.ps1 > $somefile 2>&1
When I try the above command in powershell, I see all output on console, and a 0-length file called 'output' is left behind. What gives?
EDIT: Okay, I believe most of my problem lies in the fact I'm using Write-Host, which I think bypasses the standard output stream. However, I am very worried that if I switch my Write-Host statements to Write-Output, then I'll end up corrupting the return values of all of my functions, or seriously screwing my script up some other way.
What is my most prudent option of dealing with the Write-Host entries so that I can reliably capture all output and errors to the same file? Also, I'm using colorization capabilities from Write-Host... I'm guessing I'll have to give that up if I'm looking to dump to log files.
Or even better, is it possible to set up a command-line argument, say, '-console' that controls whether Write-Host or something else is used? My script is initially being run dozens of times a day manually and interactively. It will then run once an hour every day for years to come, where logs of all output/errors will be desired.
Instead of doing
myScript.ps1 > $somefile
You can do
powershell myScript.ps1 > $somefile
I'd focus my efforts on start and stop transcript. I use it in a 3-tier system involving a client calling a script on a server that proxies a call to another server via PSRemote, and it does a splendid job for me. The output is clean and easily parsed.
It fails with native commands, unless you pipe its output to Out-Default. And you can't get to fancy with it. One transcript is all you get at a time, but one's enough.