How to use ".\" in -file in a command file - powershell

I need to execute a command file (B.cmd) on Machine B from a Powershell script (A.ps1) on Machine A. I don't want to statically specify the path
B.cmd is supposed to execute C.ps1 which is in the same folder as B.cmd
MACHINE A: A.ps1
MACHINE B: B.cmd, C.ps1 (all in same folder)
so my command file looks like this B.cmd
#echo off
powershell.exe -file ".\C.ps1" -Iterations 10
echo
echo
pause
There's an error thrown in a A.ps1 file from which I'm calling the B.cmd file
A.ps1
Invoke-Command -ComputerName $systemName -credential $credentials -ScriptBlock {Invoke-Expression -Command: "cmd.exe /c C:\Temp\Batch\Test\B.cmd"}
A.ps1 throws error:
**The argument '.\C.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.**
+ CategoryInfo : NotSpecified: (The argument '....File parameter.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : XXX
How do I make the .\ work or is there an alternative or is it wrong to use the .\ for a remote execution ?
Please forgive my ignorance anywhere as I'm very very new to PS, Thank You !

If you're able to change the ABC.cmd you could use the following
powershell.exe -file "%~dp0\XYZ.ps1"
This will get the folder the ABC.cmd script is running from. Note that %~dp0 won't work in cmd for testing you'll need to test it from within a script.

So don't wrap a batch file around it. A waste of time and confuses the issue.
invoke-command -comp $computername -filepath C:\Temp\Batch\Test\XYZ.ps1
If you need to run something 10 times, do it in a loop inside your PS script.

Related

Run a powershell script with different credentials

I'm trying to run a powershell script to search for a network drive for a certain file. In my testing, I've found that my script works perfectly fine, however the network drive I need to search require my Domain Admin logon.
I have
Start-Process powershell.exe -Credential "domain\adminusername" -NoNewWindow -ArgumentList "Start-Process powershell.exe -Verb runAs"
as the very first line of my script, but whenever I run the script I get this error:
Start-Process : This command cannot be run due to the error: The directory
name is invalid.
At Path\to\script.ps1:1 char:1
+ Start-Process powershell.exe -Credential "domain\adminusername" -NoN ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Process],
InvalidOperationException
+ FullyQualifiedErrorId :
InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
What directory name is it talking about? If I move the script to the actual network drive, I still get the same error. How do you run a script as a different user?
You could use the net use command to gain access or the new-psdrive command instead. Another option would be to start-process a cmd prompt and use runas within it. Also, you may need to include the full path of powershell.exe or add it to the path variable. %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

How do I run a *.exe file from PowerShell

I have a folder at C:\Folder that has files input.xml, output.xml and licensegenerator.exe. Licensegenerator.exe takes variables that we put into input.xml and creates a temporary license for one of our programs using the output.xml file. We typically do this via command line by navigating to the C:\Folder directory, then running the command:
LicenseGenerator.exe "C:\Folder\input.xml" "C:\Folder\output.xml"
I'm attempting to write a script to do the exact same thing in PowerShell, but I'm struggling... Here's what I have:
$inputtest = "C:\Folder\Input.xml"
$outputtest = "C:\Folder\Output.xml"
$licensegen = "C:\Folder\LicenseGenerator.exe"
Invoke-Command $licensegen "$inputtest" "$outputtest"
When I run this, I get the error:
Invoke-Command : A positional parameter cannot be found that accepts argument
'C:\Folder\Output.xml'.
At line:5 char:1
+ Invoke-Command $licengegen "$inputtest" "$outputtest"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
I have also tried running with Invoke-Expression but get the exact same error (except it says "Invoke-Expression" at the beginning). Anybody have any idea what I'm doing wrong here?
You're looking for the call operator (&):
& $licensegen "$inputtest" "$outputtest"
Invoke-Command is essentially for running scriptblocks on other hosts and/or in other user contexts.
Start-Process
is great because you can runas, redirect output, hide the child processes window and much more.
Start-Process -FilePath $licensegen -Argumentlist $inputtest,$outputtest
& "[path] command" [arguments]
Just replace Invoke-Command with &

Powershell null pointer exception

I've been working on and off on a project to compress and move files older than x days to an archival folder. I've retrofitted the script here: https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Compress-Log-121e63b5 to assist me however I'm running into an issue that has proved fairly annoying.
When I run this on my machine, utilizing local directories, the script completes as expected. However, when I pass networked file paths to the script, the Get-WmiObject query begins returning null results.
For example, this is a sample command line that works:
powershell -executionpolicy remotesigned -File compress_and_move_files.ps1 c:\temp\ c:\temp\compress_test\ 14
When I move to a UNC path, I begin getting the null-valued expression error on the WMIQuery.Compress() call
powershell -executionpolicy remotesigned -File compress_and_move_files.ps1 \\server1\temp\ \\server1\temp\compress_test\ 14
This is the full error:
You cannot call a method on a null-valued expression.
At compress_and_move_files.ps1:14 char:23
+ If ($WMIQuery.Compress <<<< ()) {Write-Host "$FullName compressed successfull
y."-ForegroundColor Green}
+ CategoryInfo : InvalidOperation: (Compress:String) [], RuntimeE
xception
+ FullyQualifiedErrorId : InvokeMethodOnNull
That script attempts to retrieve a CIM_DataFile instance - a class that isn't accessible via UNC paths in WMI.
Change the script to target the remote computer and then use the local file system path:
$Server = "server1"
$WMIFile = "C:\temp\".Replace("\", "\\")
$WMIQuery = Get-WmiObject -Computer $Server -Query "SELECT * FROM CIM_DataFile WHERE Name='$WMIFileName'"

PowerShell Start-Process -redirectStandardOutput throws: The system cannot find the file specified

In a PowerShell window I am executing:
Start-Process XXXXX.exe -ArgumentList "some valid arguments" -wait
-redirectStandardOutput "D:\\test1.txt"
And getting:
Start-Process : This command cannot be executed due to the error: The system cannot find the file specified.
At line:1 char:14
+ Start-Process <<<< XXXXX.exe -ArgumentList "some valid arguments here" -redirectStandardOutput "D:\\test1.txt"
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
I have checked that the start-process works as expectedif I omit the -redirectStandardOutput argument (it does).
The test1.txt is a NEW file, not trying to append.
The suprising thing is that the test1.txt file on D:\ is created when I run the line, it just remains empty.
Has anyone any idea what is happening here?
Thanks.
EDIT
I discovered that if I run:
Start-Process XXXXX.exe -ArgumentList "some valid arguments" -wait
-redirectStandardOutput "D:\\test1.txt"
it fails (as originally posted)
If I run:
Start-Process XXXXX.exe -ArgumentList "some valid arguments" -wait
it works fine but doesnt save the console output to a file
and if I run
Start-Process .\XXXXX.exe -ArgumentList "some valid arguments" -wait
-redirectStandardOutput "D:\\test1.txt"
It works pretty much as expected.
So why do I need to specify the path when I am using the redirection but when I am not it runs happily?
EDIT
To recapitulate the problem; there appears to be some inconsistancy regarding the requirement that scripts/exes in the current directory require a ./ prefix to be allowed to run. When I am not redirecting the output the ./ is NOT required. Anyone know if this is expected behavior?
RichyRoo,
The issue you're seeing is most likely because your XXXXX.exe location isn't registered inside your PATH environment variable.
If you try to run your command using an application registered inside one of the folders defined inside your PATH environment variable, it should work without the trailing .\
ie:
Start-Process cmd.exe -ArgumentList "/c ping 127.0.0.1" -redirectStandardOutput "D:\ABC\test.txt" -Wait
I tried a 2nd example using a sample batch file and it doesn't work without prefixing the path by .\ - It replicates your behavior.
So it works on your end by qualifying your .exe location by prefixing your xxxxx.exe with .\ as I assume your current directory in your shell is your .exe location.
I haven't looked up why current path isn't being looked at the command execution level though.

Powershell: Running a .msc applet as another user

I'm currently writing a powershell script that asks for a single set of admin credentials, and uses those to run relevant applications, pulled from a network-hosted CSV. When I try to run
Start-Process $tools[$userInput-1].path.toString() -credential $credential
(where $tools is returning "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc") I get the error below
Start-Process : This command cannot be executed because the input "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc" is an Invalid Application. Give a valid application and Run your command again.
At line:1 char:14
+ Start-Process <<<< "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc" -credential
Get-Credential
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
If I need to, I'll just write a .bat file and run that, but I'd rather avoid that whenever possible.
And the reason I'm not using Invoke-Item is because it can't take -Credential, even if the man file says otherwise.
.msc is a saved console file, the host of which is mmc, so to start this from powershell you could use syntax similar to the following:
$mmcPath = "C:\Windows\System32\mmc.exe"
$mscPath = "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc"
Start-Process -FilePath $mmcPath -ArgumentList $mscPath