Powershell remote script execution issue - powershell

I am trying to execute a powershell script from the host 1.2.3.3 on the box 1.2.3.4 remotely
$cred = get-credential
$process = get-wmiobject -query "SELECT * FROM Meta_Class WHERE __Class = 'Win32_Process'" -namespace "root\cimv2" -computername 1.2.3.4 -credential $cred
$results = $process.Create("powershell.exe /c C:\Windows\temp\hello.ps1 arg1")
I can see the process getting created (as the return value says 0) but the process is dies down immediately in the remote system(1.2.3.4)
I tried powershell.exe -file option also instead of powershell.exe /c
I tried using Invoke-Command but that dosent work because of trusted hosts issue.
Can somebody shed some light on this?

PowerShell.exe parameters starts with a dash (e.g '-'), for full help type: PowerShell.exe /?.
What do you expect to happen? What the script is doing? Should it "die" this way?

Related

Accessing cmd remotely using PowerShell

I need to run a couple of bcdedit commands on a remote computer's cmd using a PowerShell script that runs on my computer. I am able to create a PSSession but I'm not sure how I can run cmd on the remote computer. When I run the code in the 'Invoke-Command' line, I get an error Connection to remote server failed with the following error message: Access is denied. When I just run Invoke-Command, I am prompted to enter the ScriptBlock, but when I do, I get yet another error: "Cannot bind parameter 'ScriptBlock' Cannot convert the "cmd /c 'bcdedit /copy {current} /d "Description"'} value of type System.String to type System.Management.Automation.ScriptBlock
I have never worked with PowerShell before. I need to do this in a couple of hours, and I am absolutely clueless right now.
Enable-PSRemoting -Force
Set-Item WSMan:\localhost\Client\TrustedHosts $ip -Concatenate -Force
$session = New-PSSession -ComputerName $ip -Credential $cred -ConfigurationName $config -UseSSL -SessionOption $sessopt
#problematic code
Invoke-Command -ComputerName $ip -ScriptBlock {cmd /c 'bcdedit /copy {current} /d "Description"'}
#works fine
Restart-Computer -ComputerName $ip -Force
ping.exe -t $ipaddr | Foreach{"{0}-{1}" -f (Get-Date -f "yyyy/MM/dd HH:mm:ss"), $_}
Assume that $ip, $ipaddr, $config, $sessopt and $cred store valid parameters.
You can run bcedit.exe directly in PowerShell, but because in PowerShell { and } are metacharacters, you need to quote identifiers such as {current}:
bcdedit /copy '{current}' /d 'Description'
See this answer for a discussion and list of PowerShell's metacharacters.
If you get an error on connecting to a remote computer, the implication is that your user account either doesn't have sufficient privileges to connect remotely or the target computer isn't set up for PowerShell remoting.
Note that Enable-PSRemoting -Force must be run on the target (server) machine, not on the calling (client) machine.
See the conceptual about_Remote_Troubleshooting topic.
The Restart-Computer cmdlet's -ComputerName parameter does not use PowerShell remoting, so the fact that it succeeds does not imply that PowerShell remoting, such as via Invoke-Command, works.
When I just run Invoke -Command, I am prompted to enter the ScriptBlock
PowerShell's automatic prompting feature for mandatory parameter values that weren't specified on the command line has severe limitations, and not being able to prompt for a script-block parameter value is one of them - see GitHub issue #4068; however, this additional problem is incidental to your real problem.
Thanks for all the suggestions, I was able to fix the error by adding -Credential to the Invoke-Command and Restart-Computer commands:
#problematic code
Invoke-Command -ComputerName $ip -Credential $cred -ScriptBlock {cmd /c 'bcdedit /copy {current} /d "Description"'}
Restart-Computer -ComputerName $ip -Credential $cred -Force

Power shell Invoke remote script is not working

I am trying to invoke a remote bat file from my local machine that should start and run the bat in a remote machine terminal. My script is able to connect and show me the output. However, it is invoking the remote bat file but waiting on my screen with bat file output. and my idea is the bat file should invoke and running in the remote machine rather than showing the output on my terminal local terminal. What should be the way here?
loop{
Invoke-Command -ComputerName $computer -credential $cred -ErrorAction Stop -ScriptBlock { Invoke-Expression -Command:"cmd.exe /c 'C:\apacheserver.bat'" }
}
From what I understand you want the .bat file to not show you the result. If so, you should do it with the Out-Null or by redirecting STDOUT and STDERR to NULL.
IE: Invoke-Expression -Command:"cmd.exe /c 'C:\apacheserver.bat'" | Out-Null
If I'm understanding correctly, you want to suppress the output from the .bat file inside your local console? If so, redirecting to some form of $null is the way to go. You also shouldn't need Invoke-Expression as Invoke-Command can run the file directly:
Invoke-Command -ComputerName $computer -Credential $cred -ErrorAction Stop -Scriptblock {
cmd.exe /c 'C:\apacheserver.bat' | Out-Null
}
You could also use > $null instead of Out-Null if you prefer.
If you want to redirect the output of the Invoke-Command call to the remote console instead, that kind of defeats the purpose of the cmdlet. You could try redirecting the console output to a file on the remote computer if you want a local record:
$remoteFile = '\\server\C$\Path\To\Output.txt'
Invoke-Command -ComputerName $computer -Credential $cred -ErrorAction Stop -Scriptblock {
cmd.exe /c 'C:\apacheserver.bat' > $remoteFile
}
If I understand you, you want to run the script in the background and not wait for it:
Invoke-Command $computer -Credential $cred { start-process C:\apacheserver.bat }

Invoke-WmiMethod - Quickly fix PsRemoting/WinRM problems (for Invoke-Command usage)

In the event you have computers that are unreachable with Invoke-Command either because WinRm is not running or PsRemoting is disabled here is a good, sure way I've found works everytime, in my environement at least:
$target_comp = "abc1234"
Invoke-WmiMethod -ComputerName $target_comp -Path win32_process -Name create -ArgumentList "powershell.exe -command Enable-PSRemoting -SkipNetworkProfileCheck -Force"
Invoke-WmiMethod -ComputerName $target_comp -Path win32_process -Name create -ArgumentList "powershell.exe -command winrm quickconfig -quiet"
do {
$testpsremoting = invoke-command -computername $target_comp -scriptblock {"test"}
} while (!$testpsremoting)
#REST OF CODE
Explanation :
-Declare variable of your computer name.
-Run the two commands to enable PsRemoting and setup WinRM via Invoke-WmiMethod.
*Since Invoke-WmiMethod returns instantly without WAITING for the commands to actually be done:
-Make a loop that runs until PsRemoting is enabled (until the test Invoke-Command works).
No more Invoke-Command problems! Enjoy and fine tune to your heart's content.
You could use Get-wmi to get the result directly
Get-WmiObject Win32_service -ComputerName $poste | select State,Name,DisplayName
Question changed to provide answer and useful fix for the community.

Executing batch file in the remote machines using powershell as a background job

All I am trying to do is to execute a batch file in remote machines as a job.I have batch file located in all machines inside C:\Users\temp folder.Here is my code
$batFile = "test.bat"
foreach($m in $machine)
{
Invoke-Command -ComputerName $m -ScriptBlock{param($batFile) & cmd.exe /c "C:\Users\temp\$batFile"} -Authentication negotiate -Credential $cred -ArgumentList $batFile -AsJob
}
But I keep getting
The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script
block, or a CommandInfo object
I tried using $using:batFile inside ScriptBlock as well with no success. Can anyone suggest me what I might be doing wrong? I am using powershell version 4.
do a trace on that,
Invoke-Command -ComputerName $m -ScriptBlock{param($batFile) Trace-Command NativeCommandParameterBinder -Expression { & cmd.exe /c "C:\Users\temp\$batFile"}} -Authentication negotiate -Credential $cred -ArgumentList $batFile -AsJob
and Try using Invoke-Expression as a workaround instead of &
invoke-Expression "cmd.exe /c 'C:\Users\temp\$batFile'"
Regards,
Kvprasoon

Determine PowerShell version remotely via WMI

I have searched here and elsewhere and could not find an answer, so here is my question.
What is the best way to determine PowerShell version on a remote computer using WMI?
Background
My task is to audit and update some 1000 servers to recent version of PowerShell. Some of them have PowerShell v1 and some do not have WinRM configured, so Invoke-command is not an option. PSExec is also not an option in this environment. This is why I need to use WMI for this task.
Any help would be appreciated.
EDIT:
After much research I'm still leaning towards WMI. In particular retrieving the file version of "powershell.exe". This seems to me to be the only way to cover all versions.
Code I have so far is here:
$path = "C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"
$query = "SELECT Version FROM CIM_DataFile WHERE Name = '$path'"
$PSFileVer = Get-WmiObject -Query $query -ComputerName $servername -Credential $creds
$BuildVer = [version]$PSFileVer.Version.Split()[0]
All I need now is a comprehensive list, mapping file version (build number) to powershell version. Any Ideas?
The solution from here is
$command = "ipconfig/all > C:\temp\result.txt"
$cmd = "cmd /c $command"
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList $cmd -ComputerName "remotepc"
sleep 1
Get-Content \\remotepc\C$\temp\result.txt
You can also do similar via this method. If you do so, you can't get the return value directly, u must redirect to a file.
You could setup share for the results instead of putting result on local machine
If it helps here is the command :
$command = "powershell -command "+'"$PSVersionTable.PsVersion.Major | out-file c:\temp\version.txt"'