Calling Patch.exe from Powershell with p0 argument - powershell

I'm currently trying to patch some files via PowerShell using Patch.exe
I am able to call the exe using the '&' command, but it doesn't seem to be reading my p0 input. I'm not an expert on PowerShell and any help would be appreciated!
here is what I am calling in PS:
$output = & "$scriptPath\patch.exe" -p0 -i $scriptPath\diff.txt
My error reads:
can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
Which I can emulate by leaving out the p0 parameter on my patch file from commandline.
Here are some alternatives I've already tried:
#$output = & "$scriptPath\patch.exe" -p0 -i "$scriptPath\diff.txt"
#CMD /c “$scriptPath\patchFile.bat” (where patchFile.bat has %~dp0patch.exe -p0 < %~dp0diff.txt, seems like powershell reads < as 0<, so there is an error there I think)
#GET-CONTENT $scriptPath\diff.txt | &"$scriptPath\patch.exe" "-p0"
#GET-CONTENT $scriptPath\diff.txt | CMD /c “$scriptPath\patch.exe -p0”
Thanks!

Try:
$output = & "$scriptPath\patch.exe" -p0 -i "$scriptPath\diff.txt"

Patch.exe started in the wrong context and I solved this by using Push-Location / Pop-Location
Here is what my code looks like now
Push-Location $scriptPath
$output = & "$scriptPath\patch.exe" -p0 -i "$scriptPath\diff.txt"
Pop-Location
Keith also mentioned in one of his comments that you can use:
[Environment]::CurrentDirectory = $pwd
I have not tested this, but I assume it does the same thing (Keith is a powershell MVP, I am just a student).

Related

Multiple Powershell command needs to be run from command line

i need to run single line powershell script like this one:
$a = Get-Content test.tmp; $b = [timespan]::fromseconds($a); "{0:HH:mm:ss,fff}" -f ([datetime]$b.Ticks)
in command line. When running it directly from powerhsell cli it work fine. but when trying run:
powershell "$a = Get-Content test.tmp; $b = [timespan]::fromseconds($a); "{0:HH:mm:ss,fff}" -f ([datetime]$b.Ticks)"
from command line cli i get error. I cannot run it from script in form of .ps1 file as i am not allowed to change restriction policy regarding to run powershell script.
Anybodoy would be able to point me what i have to change to run it properly from command line?
Many thanks
With proper quoting / parentheses you need no intermediate variables and only one command:
'{0:HH:mm:ss,fff}' -f ([datetime]([timespan]::fromseconds((Get-Content test.tmp))).Ticks)
In a batch:
powershell -C "'{0:HH:mm:ss,fff}' -f ([datetime]([timespan]::fromseconds((Get-Content test.tmp))).Ticks)"
Or to get the duration into a batch variable:
:: Q:\Test\2017\09\23\SO_46379453.cmd
#Echo off
For /f "tokens=1*" %%A in (
'powershell -C "\"{0:HH:mm:ss,fff}\" -f ([datetime]([timespan]::fromseconds((Get-Content test.tmp))).Ticks)" '
) Do Set "Duration=%%A,%%B"
set Duration

Add date to redirected file name in windows powershell

There must be a solution already here, but I can't find it ... what I'd like to do:
Make a link on the windows desktop, double clicking this link will execute a batch.bat and outputs something on stdout and stderr, I'd like to have the output on the console and also in a logfile.
For this part I ended with something like this:
powershell.exe -NoExit C:\mypath\mybatch.bat | tee 2>&1 mylog.log
This does what I want, but I'd like to have the log file named something like mylog-20160317-2125.log
I know that in powershell there's something like [datetime]::now.tostring("yyyyMMdd-HHmm") and Get-Date -f yyyyMMdd-HHmm
But how can I put one or another in my command line above to get the wanted log file name?
Thanks for any help ...
Use something like:
powershell.exe -NoExit C:\mypath\mybatch.bat | tee 2>&1 "mylog-$(Get-Date -f yyyMMdd-HHmm).log"

Compressing to tar.xz using 7-zip through a pipe on windows

My command line is this (powershell):
$7z ="`"c:\Program Files\7-Zip\7z.exe`""
&$7z a -r -ttar -bd -so . | &$7z a -r -txz -bd $archive -si
The produced archive file indeed contains a tar file, but that tar file is corrupt.
Note, that breaking the pipe into two commands works correctly:
&$7z a -r -ttar -bd ${archive}.tmp .
&$7z a -r -txz -bd $archive ${archive}.tmp
The produced archive is perfectly valid.
So, what is wrong with my pipeline?
(I am using Powershell)
Nothing is wrong with your pipeline it is the way that the pipeline works that's causing the error.
PowerShell pipe works in an asynchronous way. Meaning that output of the first command is available to the second command immediately one object at the time even if the first one has not finished executing, See here.
Both Unix and PowerShell pipes operate in the same way. The reason why you might be seeing a difference from Unix to PowerShell is the way in which they go about it is different.
Unix passes Strings between the commands. Where as a Powershell pipe will pass full-fledged .net object between commands. This difference in the data type being past between command will be why it works on unix and not in PowerShell. If 7z.exe can not huddle these .net objects correctly the files will be come corrupt, See here.
Try adding | %{ "$_" } in between the pipes like
&$7z a -r -ttar -bd -so . | %{ "$_" } | &$7z a -r -txz -bd $archive -si
The point is that the second call to 7z expects unmodified data on STDIN, but PowerShell is converting the output from the first call to 7z to (multiple) (string) objects. % is an alias for foreach-object, so what the additional command does is to loop over each object and convert it to a plain string before passing it on to the second call to 7z.
Edit: Reading through PowerShell’s Object Pipeline Corrupts Piped Binary Data it looks to me now as if my suggestion would not work, and there's also no way to fix it. Well, other than wrapping the whole pipeline into a cmd /c "..." call to make cmd and not PowerShell handle the pipeline.
Edit2: I also was trying this solution from the PowerShell Cookbook, but it was very slow.
In the end, I created a .cmd script with the 7z pipes that I'm calling from my PowerShell script.

How do I change directory and run a file in that directory in powershell?

For example, i want to run cygwin.bat which is located in the c:/cygwin/ directory...
I tried the following but got an error:
cd c:/cygwin ./cygwin.bat
cd c:/cygwin and ./cygwin.bat are two different statements. You can execute them from the interactive console like so:
PS C:\> cd c:/cygwin
PS C:\cygwin> ./cygwin.bat
Or, if you really want to do it on the same line, then use a ; between them to indicate separate statements.
cd c:/cygwin ; ./cygwin.bat
best way is the way its always been
c:\cygwin\cygwin.bat
it's all you need to type
Try iex
$command = "cd c:/cywin"
iex $command

Perl: can not get correct exit code from external program

I've searched everywhere, but I can't seem to find a solution for my issue. Probably, it is code related.
I'm trying to catch the exit code from a novell program called DXCMD, to check whether certain "drivers" are running. This is no problem in bash, but I need to write a more complex perl script (easier working with arrays for example).
This is the code:
#Fill the driverarray with the results from ldapsearch (in ldap syntax)
#driverarray =`ldapsearch -x -Z -D "$username" -w "$password" -b "$IDM" -s sub "ObjectClass=DirXML-Driver" dn | grep ^dn:* | sed 's/^....//' | sed 's/cn=//g;s/dc=//g;s/ou=//;s/,/./g'`;
#iterate through drivers and get the exit code:
foreach $driverdn (#driverarray)
{
my $cmd = `/opt/novell/eDirectory/bin/dxcmd -user $username -password $password -getstate "$driverdn"`;
my $driverstatus = $?>>8;
}
I've come this far; the rest of the code is written (getting the states).
But the $?>>8 code always returns 60. When I copy the command directly into the shell and echo the $?, the return code is always 2 (which means the driver is running fine). In bash, the code also works (but without the >>8, obviously).
I've looked into the error code 60, but I cannot find anything, so I think it is due to my code.
How can I rectify this error? Or how can I track the error? Anyone? :)
Wrong value passed to -getstate. You didn't remove the newline. You're missing
chomp(#driverarray);