Passing a .txt file to a Powershell command - powershell

I am trying to pass a .txt file with arguments to an .exe file via powershell. Currently, this is what I have.
Write-Host "starting upgrade at $(Get-Date -format 'U')"
C:\dev\temp.exe.exe /DIR="C:\TEST" /BTPServerHost="Test" /DBInstance="testDB" /Log=C:\path\to\test\testlog.txt
This is calling a function within an InnoScript file that accepts command line input.
How would I format the .txt file, and how would I be able to pass it into the .exe? Any help would be appreciated! Thanks!

If you are saying, in this text file, there are just these argument line on individual rows and you are saying you've already tried something like the below and were not successful?
You also don't need the Write-Host for the message line, since the default is output to screen. You normal only need Write-Host for colorizing screen text, and a few other formatting cases, depending on what you are doing. All-in-All, Write-Host should be avoided.
"starting upgrade at $(Get-Date -format 'U')"
($ConsoleCommand = Get-Content -Path 'd:\temp\input.txt' -Raw)
# Results - showing the commands in the file before process them
whoami
get-date
'hello world'
Without using the -Wait switch, this will spawn 3 separate PowerShell consoles with the results
ForEach($CmdLine in $ConsoleCommand)
{ Start-Process -FilePath powershell -ArgumentList "-NoExit","-Command &{ $CmdLine }" }
you can of course point to your .exe vs what I am doing here.
Start-Process
By adding the -Raw after specifying the .txt file path it ignores newline characters and returns the entire contents of a file in one string with the newlines preserved. By default, newline characters in a file are used as delimiters to separate the input into an array of strings.

This script takes parameters from a txt file and passes them into an executable and auto-populates the fields in the installation wizard. This is what I'm looking to do, but I don't want to start a new process for each argument in the input txt file.
Write-Host "starting upgrade at $(Get-Date -format 'U')" Get-Content -Path C:\TestInput.txt -Raw | foreach {Start-Process C:\dev\test.exe -ArgumentList $_}
The TestInput.txt file passed in looks like this:
/DIR="C:\TEST"
/ServerHost="Test"
/DBInstance="testDB"
/Log=C:\testlog.txt

Related

How do I print a rich text file from a Powershell script?

I'm using Powershell to automate some tasks, and I've worked out how to edit a .rtf file template and save this back to disk using $content | Set-Output $fileName
This generates a brilliant looking rtf file, complete with bolds, italics, alignment etc.
I'd now like to automatically print this file to the default printer, which is installed with the correct drivers on the machine running the script.
I'm doing this using $content | Out-Printer, but this produces what I presume is the plaintext encoding of the rtf file, rather than the actual formatted document.
Is there any way to print a rtf file with the correct formatting, or am I doomed to plaintext for eternity?
If your .rtf files have a Print option in their context menu, that can be invoked in PowerShell using Start-Process with the -FilePath and -Verb parameters. In its simplest form:
Start-Process -FilePath 'c:\rtfFiles\SomeFile.rtf' -Verb Print
And of course, in real life, the path will most likely be contained in a variable and the Cmdlet inside a loop:
Get-ChildItem *.rtf | ForEach{
Start-Process -FilePath $_.FullName -Verb Print
}

Using PowerShell to pass all files of a folder as arguments to a command line program

I'm trying to create a file listing of a folder for a secure file transfer tool. This is what I do:
Get-ChildItem c:\files | % {$_.FullName} > c:\temp\list1.csv
$csv = Import-Csv C:\TEMP\list1.csv -Header Path
The output holds every file in a new line, but I need it in one line.
Required output
"C:\files\Alpha" "C:\files\Beta" "C:\files\Gamma" "C:\files\Delta"
Actual output
C:\files\Alpha
C:\files\Beta
C:\files\Gamma
C:\files\Delta
The csv file is just what came to my mind first. A variable containing the files formatted like mentioned above would be sufficient. Do you have an idea?
Edit: Thank you #Matthias R. Jessen and #WaitingForGuacamole, you gave me exactly what I wanted.
(Get-ChildItem C:\scripts -File).ForEach({'"{0}"' -f $_.FullName.Replace('"','\"')}) -join " "
However, somehow my tool (written in java) is interpreting the output as one file instead of multiple files in a line.
Below the error message:
Java : Error: The file 'C:\files\Alpha C:\files\Beta C:\files\Delta C:\files\Gamma' was not found and is excluded from the transfer.
I know, that I have to handover the paths differently when using a properties file instead of entering the command manually in PowerShell.
Is there a way on letting the output look like:
"C:\\files\Alpha" "C:\\files\Beta" "C:\\files\Gamma" "C:\\files\Delta"
To pass the file paths of all children of a specific folder to a command line program as separate arguments, just pass the results of
(Get-ChildItem -File).FullName
to the program. Example:
$files = (Get-ChildItem C:\MyFolder -File).FullName
# Expected: myprogram.exe -arg1 -arg2 C:\MyFolder\file1.txt C:\MyFolder\file2.txt ...
myprogram.exe -arg1 -arg2 $files

Reading a file path that contains wildcard characters

I'm working on a script that takes a directory name as input, and writes a log file to that directory.
This works in most cases:
param([string]$output_folder)
$logfile="$output_folder" + "\myscript.log"
Write-Output "logfile: " $logfile
(Get-Date -Format "[yyyy-MM-dd HH:mm:ss]") | Out-file $logfile -Append
except when the file path contains a wildcard:
E:\Publishing\User manual [en]\
This results in an error 'Cannot perform operation because the wildcard path E:\Publishing\User manual [en]\myscript.log did not resolve to a file.
I spent some time trying to sanitize the input, but I haven't found a way that works yet.
$logfile='$output_folder' + "\myscript.log"
This treats the string as a literal, but that prevents $output_folder from being expanded.
param([io.directoryinfo]$output_folder)
doesn't help either.
Edit:
A comment suggested this:
Out-file -LiteralPath $logfile -Append
That works for the instances where I use Out-file.
I also call an external program, and I can't use -LiteralPath here:
"C:\Program Files\Saxonica\SaxonHE9.8N\bin\Transform.exe" -s:"$inputFile" -xsl:"$output_folder\$transformation_filename" -o:"$outputFile" -t 1>>$logfile 2>&1
in fact I have more arguments here that need to be treated as literals. Is there a way so specify this when I create the string?
$logfile="$output_folder" + "\myscript.log"

Escape spaces in PowerShell and cmd

I have a PowerShell script that is calling an .exe from the command line to create an XML file and then the PowerShell script is reading that file.
The problem is if I have a space in the file path I need to wrap in in double quotes to pass it to the command line. When I do that the PowerShell command tries to read the double quotes as part of the file path. Is there a way to escape the spaces that will work for both passing it to the command line and using commands inside PowerShell?
It seems silly to have to pull out the double quotes for one command and leave them in for another.
The issue is with the Get-Content line not liking the double quotes.
$outputpath = '"C:\Users\bob\Desktop\output new.xml"'
Start -FilePath $sqlpackage -ArgumentList "/action:DeployReport /SourceFile:$dacpacpath /Profile:$profilepath /OutputPath:$outputpath" -NoNewWindow -Wait
[xml]$xmldocument = Get-Content -Path $outputpath
Deadly-Bagel almost had it I think. Don't use double quotes in $outputpath to keep Get-Content happy, but add them in your argument list string.
Be sure to escape with backtick `. In fact you might just want to do that with all the paths:
$outputpath = 'C:\Users\bob\Desktop\output new.xml'
Start -FilePath $sqlpackage -ArgumentList "/action:DeployReport /SourceFile:`"$dacpacpath`" /Profile:`"$profilepath`" /OutputPath:`"$outputpath`"" -NoNewWindow -Wait
[xml]$xmldocument = Get-Content -Path $outputpath
-ArgumentList accepts String[] so try the following:
$outputpath = "C:\Users\bob\Desktop\output new.xml"
Start -FilePath $sqlpackage -ArgumentList #("/action:DeployReport", "/SourceFile:$dacpacpath", "/Profile:$profilepath", "/OutputPath:$outputpath") -NoNewWindow -Wait
I suspect passing it all as one parameter causes it to be confused.

Logparser and powershell with multiple logfiles in a foreach-object loop

So I'm trying to write a powershell script that will go through a folder full of .evtx files, send out each one via syslog, then append ".done" to the filename of the .evtx file after doing so.
The thing is, I'm not quite sure how to reference the current log file I am on within the Foreach-Object loop.
Hopefully the following code will explain my dillema.
# begin foreach loop
Get-ChildItem $evtxfolder -Filter *.evtx | `
Foreach-Object {
$LPARGS = ("-i:evt", "-o:syslog", "SELECT STRCAT(`' evt-Time: `', TO_STRING(TimeGenerated, `'dd/MM/yyyy, hh:mm:ss`')),EventID,SourceName,ComputerName,Message INTO $SERVER FROM $CURRENTOBJECT") #obviously, this won't work.
$LOGPARSER = "C:\Program Files (x86)\Logparser 2.2\logparser.exe"
$LP = Start-Process -FilePath $LOGPARSER -ArgumentList $LPARGS -Wait -Passthru -NoNewWindow
$LP.WaitForExit() # wait for logs to finish
If you look in $LPARGS, you'll see that I put $SERVER and $CURRENTOBJECT. Obviously, the way I have it now will not work, but obviously, that won't work. So basically, I'm trying to put the variable $SERVER (passed in as a parameter) into the arguments for logparser, and reference whatever current event log it is working on to put in the "FROM" statement so that it knows to work on one .evtx file at a time. What would be the proper way to do this?
An example of the INTO FROM statement:
..snippet..
SourceName,ComputerName,Message INTO #192.168.56.30 FROM 'C:\Eventlogs\20131125.evtx'"
Of course, 'C:\Eventlogs\20131125.evtx' would change as it goes through the contents of the directory.
If $server is defined outside your script above it will be available inside your string for $LPARGS. As for the $CURRENTOBJECT, that would be $_. In this case, it will be a FileInfo object. It is likely you want the Name property e.g. $($_.Name).