How execute a process from Power Shell script? - powershell

I'm trying to execute a process from a power shell script:
$covFiles = Get-ChildItem -Name -Path .\ -Include Cov*.xml
for ($i=0; $i -lt $covFiles.Count; $i++) {
$covFile = $covFiles[$i]
$idx = $covFile.IndexOf("_")
$covPlatform = $covFile.SubString(3, 3)
$covFilter = $covPlatform + "_" + $covFile.SubString($idx + 1).TrimEnd(".xml")
$command = "-f " + $covFile + " -F " + $covFilter
& codecov $command
}
The working directory has files named, for instance:
- CovEGLOpenGL.Net.Test_net461_x86_Release.xml
- CovWGLOpenGL.Net.CoreUI.Test_net461_x64_Release...
If I echo the command with & echo $command it works as expected on my local machine.
But on AppVeyor, the process outputs:
codecov.exe : The filename, directory name, or volume label syntax is incorrect.
At line:8 char:3
+ & codecov $command
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (The filename, d...x is incorrect.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
FIND: Parameter format not correct
This leads me to think that there's something wrong with the parameters specification. May it be quoting?
Replacing codecov with echo, locally outputs:
-f CovEGLOpenGL.Net.CoreUI.Test_net461_x64_Release.xml -F EGL_net461_x64_Release
-f CovEGLOpenGL.Net.CoreUI.Test_net461_x86_Release.xml -F EGL_net461_x86_Release
-f CovEGLOpenGL.Net.Test_net35_x64_Release.xml -F EGL_net35_x64_Release
-f CovEGLOpenGL.Net.Test_net35_x86_Release.xml -F EGL_net35_x86_Release
-f CovEGLOpenGL.Net.Test_net461_x64_Release.xml -F EGL_net461_x64_Release
-f CovEGLOpenGL.Net.Test_net461_x86_Release.xml -F EGL_net461_x86_Release
-f CovWGLOpenGL.Net.CoreUI.Test_net461_AnyCPU_Release.xml -F WGL_net461_AnyCPU_Release
-f CovWGLOpenGL.Net.CoreUI.Test_net461_x64_Release.xml -F WGL_net461_x64_Release
-f CovWGLOpenGL.Net.CoreUI.Test_net461_x86_Release.xml -F WGL_net461_x86_Release
-f CovWGLOpenGL.Net.Test_net35_AnyCPU_Release.xml -F WGL_net35_AnyCPU_Release
-f CovWGLOpenGL.Net.Test_net35_x64_Release.xml -F WGL_net35_x64_Release
-f CovWGLOpenGL.Net.Test_net35_x86_Release.xml -F WGL_net35_x86_Release
-f CovWGLOpenGL.Net.Test_net461_AnyCPU_Release.xml -F WGL_net461_AnyCPU_Release
-f CovWGLOpenGL.Net.Test_net461_x64_Release.xml -F WGL_net461_x64_Release
-f CovWGLOpenGL.Net.Test_net461_x86_Release.xml -F WGL_net461_x86_Release

This should fix the problem you're running into:
$covFiles = Get-ChildItem -Filter cov*.xml
ForEach ($File in $covFiles)
{
$Path = $File.FullName
$idx = $Path.IndexOf("_")
$Platform = $Path.Substring(3, 3)
$Filter = "${Platform}_$($Path.Substring($idx+1).TrimEnd('.xml'))"
$ArgList = #(
'-f',"`"$Path`""
'-F',"`"$Filter`""
)
Start-Process -FilePath codecov -ArgumentList $ArgList
}
I suspect the problem you are running into is due to relative paths.

Related

Invoke executable with parameters and catch error output

I need to run an executable that requires some parameters in that form
c:\Program Files\Tools\Tool -p Parameter -d .....
The executable reports something to standard output what should be ignored. The error output lines should be stored in an array of lines for further processing in PowerShell.
I tried
$err = & "c:\Program Files\Tools\Tool -p Parameter"
Invoke-Command "c:\Program Files\Tools\Tool -p Parameter" -ErrorVariable errorOutput
The former doesn't catch stderr.
The latter failed because the string contains more than the executable name. -p is not part of the executable name. If I omit the double quotes, Invoke-Command interprets the -p as abbreviation for "PipelineVariable".
How should I run the executable while getting stderr?
Edit:
Inspired by the answer of js2010 I tried this
$err = $( $output= & "c:\Program Files\Tools\Tool -p Parameter" ) 2>&1
Unfortunately the result in $err is:
Tool.exe : ==> Error: Product Bar\1.01.01 has not been found!
At line:1 char:17
+ ... = ( $out = & "c:\Program Files\Tools\Tool -p Parameter" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (==> Error: Prod...been found!:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Obviously that's not the stderr output of Tool.exe but also some PowerShell annotation.
Edit2:
The variable $err is still unusable if the & is omitted:
$err = $( $output= "c:\Program Files\Tools\Tool -p Parameter" ) 2>&1
Tool.exe : ==> Error: Product Bar\1.01.01 has not been found!
At line:1 char:17
+ ... = ( $out = "c:\Program Files\Tools\Tool -p Parameter" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (==> Error: Prod...been found!:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
You can try the below with your exe
I tested it with one of mine which takes 3 arguments and it works as expected
$proc = [System.Diagnostics.Process]::Start([System.Diagnostics.ProcessStartInfo]#{
'FileName' = "C:\Users\Vincen\Desktop\test.exe"
'Arguments' = 's d qa'
'CreateNoWindow' = $true
'UseShellExecute' = $false
'RedirectStandardOutput' = $true # to get stdout to $proc.StandardOutput
'RedirectStandardError' = $true # to get stderr to $proc.StandardError
})
$output = $proc.StandardOutput
$error1 = $proc.StandardError
#$output.ReadToEnd()
$error1.ReadToEnd()
EDIT: Added PS Version
$stdderror= "Error"
Start-Process -FilePath "C:\Users\XXXX\Desktop\Test.exe" -ArgumentList 's d qa' -RedirectStandardError $stdderror -RedirectStandardOutput $stddop -Wait
Get-Content $stdderror
$err has the error messages. Just ( ) wouldn't work. Both variables would get both outputs. Edited for your example.
$env:path += ';c:\Program Files\Tools'
$err = $( $output = Tool -p Parameter ) 2>&1

You must provide a value expression following the '-' operator error when using product code for MsiZap

This Powershell script calls MsiZap on a remote server to delete a software based on it's product code if it exists.
I'm getting a parsing error saying the following:
At C:\Scripts\Remove Tools\Remove-Tools.ps1:41 char:83
+ ... {57753043-0E65-4B13-9AF0-AC09CFC29C03} }
+ ~
You must provide a value expression following the '-' operator.
At C:\Scripts\Remove Tools\Remove-Tools.ps1:41 char:83
+ ... {57753043-0E65-4B13-9AF0-AC09CFC29C03} }
+ ~~~~~~~~~~~~~~~~~~~~~~
Unexpected token '4B13-9AF0-AC09CFC29C03' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : ExpectedValueExpression
Here's all of the switching code:
foreach ($product in $products){
Switch -wildcard($product.IdentifyingNumber){
"*C18D2775-33F4-4CE9-B071-4ECC78DA5E31*" { "Removing Software" >> "$spath\log.log"
./psexec \\$computer -s -w c:\ cmd /c msizap.exe TW {C18D2775-33F4-4CE9-B071-4ECC78DA5E31} }
"*59AB19CE-2706-4F7B-B567-403BB584D92E*" { "Removing Software" >> "$spath\log.log"
./psexec \\$computer -s -w c:\ cmd /c msizap.exe TW {59AB19CE-2706-4F7B-B567-403BB584D92E} }
"*57753043-0E65-4B13-9AF0-AC09CFC29C03*" { "Removing Software" >> "$spath\log.log"
./psexec \\$computer -s -w c:\ cmd /c msizap.exe TW {57753043-0E65-4B13-9AF0-AC09CFC29C03} }
"*4B932CA6-727B-4948-91E3-FFCF75CE3478*" { "Removing Software" >> "$spath\log.log"
./psexec \\$computer -s -w c:\ cmd /c msizap.exe TW {4B932CA6-727B-4948-91E3-FFCF75CE3478} }
}
}
The following line is the one causing the error:
"*57753043-0E65-4B13-9AF0-AC09CFC29C03*" { "Removing Software" >> "$spath\log.log"
./psexec \\$computer -s -w c:\ cmd /c msizap.exe TW {57753043-0E65-4B13-9AF0-AC09CFC29C03} }
The other lines, which are identical (besides the change in product code) do not get this error.

Error when I want to rename the files generated in a for loop in powerShell

Here is my for loop
function Generate_bin($input_1, $bin_file_name, $Codes){
$counter=1
foreach ($Code in $Codes)
{
Write-Host "Code = $Code"
$input_11 = "$input_1" + "$counter"
$pattern = "0x"
$New = ""
$Code = [regex]::replace($Code, $pattern, "$New")
$bin_file_name2 = "$bin_file_name"
$bin_file_name2 += "$Code" + ".bin"
#This utility generates "out.bin"
Invoke-Command -ScriptBlock {.\xyz.exe -i -t "$input_1"}
Rename-Item out.bin -NewName $bin_file_name2
$counter++
}
}
I am getting following error
Rename-Item : Cannot create a file when that file already exists.
At C:\script\myParser_unique.ps1:18 char:7
+ Rename-Item out.bin -NewName $bin_file_name2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Users\v-ashi...Unified\out.bin:String) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
You should add -Force parameter to the Rename-Item to make it overwrite existing files.
If your code happens to generate multiple equal file names you could add a counter to the filename.

execute ftp with white space in path

The following PowerShell script runs an ftp command but returns an error as it cannot get find the absolute source path (which includes white space and does take the complete path as "File One” and “Destination One".
Output:
/usr/bin/lftp -c \"mirror --only-missing --verbose sftp://jason#10.1.1.1:/e:/Files/File One e:/Files/Destination One/File One\"
Access failed: No such file (e:/Files/File)
The values of each variables are hardcoded and cannot be changed for a reason. In that case, what are the changes required in the $ftppath or $ftpcmd to include these white spaces in the source and dest, so it can return the ftpcmd correctly. Could someone please help?
Script:
# these values are hardcoded and cannot be modified
$root = "/e:/Files"
$source = "File One"
$dest = "e:/Files/Destination One/File One"
$user = "jason"
$server = "10.1.1.1"
# ftp command
$ftppath = "sftp://$user" + '#' + $server + ':' + $root + '/' + $source + ' ' + $dest
$ftpcmd = '/usr/bin/lftp -c \"mirror --only-missing --verbose ' + "$ftppath"+'\"'
$ftpcmd
Invoke-Expression -command $ftpcmd
so i guess you can simply use it like thi:
# these values are hardcoded and cannot be modified
$root = "/e:/Files"
$source = "File One"
$dest = "e:/Files/Destination One/File One"
$user = "jason"
$server = "10.1.1.1"
# ftp command
$ftppath = "sftp://$user" + '#' + $server + ':' + $root + '/' + $source + ' ' + $dest
$ftpcmd = '/usr/bin/lftp -c \"mirror --only-missing --verbose ' + "$ftppath"+'\"'
$ftpcmd
Invoke-Expression -command $ftpcmd.replace(" ", "\ ")
```shell
ftp command
$ftppath = "sftp://$user" + '#' + $server + ':' + $root + '/' + $source + ' ' + $dest
```
replace by this,use quote wrap $dest
```shell
ftp command
$ftppath = "sftp://$user" + '#' + $server + ':' + $root + '/' + $source + ' ' + "${dest}"
```

Quote Madness in Powershell

I'm using invoke-expression in PowerShell to create an archive, but it's not working due to spaces in the exe path. These are my variables:
Set-Variable -name DIRRELEASE -value (Join-Path $env:UserProfile "\Documents\Coding\_Projects\ChickenPing\trunk\Dist\current\")
$srcPath = (Join-Path $DIRRELEASE ("myapp_1.90-src.zip"))
Set-Variable -name WinRarFilter -value "-x*\.svn -x*\.svn\* -x*\nutrition.db3"
Set-Variable -name WinRarOpts -value "-r -s -m5 -inul"
$WinRar = `"C:\Program Files\Winrar\winrar.exe`"
#Then using this to invoke:
Invoke-Expression ($WinRAR + " a " + $srcPath + " " + $WinRARFilter + " * " + $WinRAROpts)
When I run the script I get this error:
The term 'a' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try
again. At line:1 char:3
+ a <<<< C:\Users\Echilon\Documents\Coding_Projects\MyApp\trunk\Dist\c
urrent\myapp_1.95-src.zip -x*.svn -x*.svn* -x*\nutrition.db3 * -r
-s - m5 -inul
+ CategoryInfo : ObjectNotFound: (a:String) [], CommandNotFoundEx ception
+ FullyQualifiedErrorId : CommandNotFoundException
I just can't find the right combination of quotes and plusses.
You could make this a lot easier to work with by using the call operator &.
& $WinRAR a $srcPath "-x*\.svn" "-x*\.svn\*" "-x*\nutrition.db3" * -r -s -m5 -inul