Run Powershell script from WebClient.DownloadString on the Command Prompt - powershell

On the Command Prompt, I want to run a PowerShell script that is stored at a URL.
Here is what I have tried:
powershell -c "iex ((New-Object System.Net.WebClient).DownloadString('http://192.X.X.X/Sherlock.ps1'))"
powershell -Command "& iex (New-Object System.Net.WebClient).DownloadString('http://192.X.X.X/Sherlock.ps1')"
powershell -NoProfile -Command "iex ((New-Object System.Net.WebClient).DownloadString('http://192.X.X.X/Sherlock.ps1'))"
powershell.exe -exec Bypass -C "IEX (New-Object Net.WebClient).DownloadString('http://192.X.X.X/Sherlock.ps1')"
I have ran each of them for 5 minutes and nothing really showed the results I wanted. It displays no error but nothing really happen after waiting.
I want to know why the above scripts does not work as intended?
I will achieve the result I want by typing this instead:
echo IEX (New-Object Net.WebClient).DownloadString('http://192.X.X.X/Sherlock.ps1') | powershell -NoProfile -Command -
My question is similar to:
Run Powershell script from URL without temporary file
Other references:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1
https://gist.github.com/jivoi/c354eaaf3019352ce32522f916c03d70

There is more than one method, but here's a quick one-liner that should do the trick from the command prompt:
powershell -ExecutionPolicy Bypass -Command "[scriptblock]::Create((Invoke-WebRequest "https://gist.githubusercontent.com/ChrisKibble/afea9880a184cd2b2445e5d8408715af/raw/41cbbf042af07136132f09395e4664ffab33e310/gistfile1.txt").Content).Invoke();"
This creates a script block based on the content of a file hosted at a URL.
As to why yours don't work, it's tough to say without debugging it or doing some process monitoring, but my first guess would be something wrong with your PS1 file (try something simple like just a Write-Host).

Related

Batch file to run PowerShell Script Only Works Once

So I'm trying to create a batch file to run a PowerShell script while bypassing the execution policy. Oddly, it worked a single time, but without me editing anything, it will not run again. I've created other files thinking maybe my file somehow got corrupted, but nothing... Any chance someone sees anything blatantly wrong with this?
#echo off
Powershell.exe -Command "& {Start-Process Powershell.exe -ArgumentList '-ExecutionPolicy Bypass -File %~dp0File.ps1' -Verb RunAs}"
PAUSE
The *.ps1 file works by itself if I click through the prompts. Also, if I manually set the execution policy in PowerShell to Bypass, this batch file still does not work. This is not a process I usually need to take, so I'm curious if anyone sees anything wrong with how this is written?
If this is just to run your script, what I personally do is create a shortcut of the script and then modify the Target of the shortcut:
Target: Powershell.exe -ExecutionPolicy Bypass -File "C:\scriptpath\script.ps1"
If you want your script to be executed as Administrator you can add this to the top of the main script:
$myInvoke="-file `"$($MyInvocation.ScriptName)`""
Start-Process "$PSHome\powershell.exe" -Verb Runas -ArgumentList $myInvoke -EA 'Stop'
If the shortcut will always be in the same folder as your script you can also leave Start In blank and change the path for Powershell.exe -ExecutionPolicy Bypass -File ".\script.ps1" by doing so if you copy the entire folder to a different location, the shortcut will still work.

Calling a Powershell script from Batch script..But need the batch script to wait for the Powershell script to complete

I have a batch script being that has the following code in it:
Here is the batch script (Test.bat):
call powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1
exit /b
The Powershell script (TheScriptToBeExecuted.ps1) has some wait built into it. But when this file is being called, the batch script is NOT waiting for the Powershell script to finish.
I ever tried:
START /wait powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1
To no effect.
When I double click on the Test.bat file, it seems to be waiting. I have checked out a lot of answers, but couldnt find any that correspond to this issue.
Please help.
start /wait powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1 | ECHO > nul
Try the above. Holds the command until scripts executed, without the Teminate Batch Prompt. Use start /min /wait if not needing to display or interact with the script, or Alternately:
start /wait powershell.exe -executionpolicy remotesigned -WindowStyle Hidden -File TheScriptToBeExecuted.ps1 | ECHO > nul
-WindowStyle Value
Sets the window style for the session. Valid values are Normal, Minimized, Maximized and Hidden.
* | * pipes the output of the command, however as your just starting powershell.exe and not using it in the context of utilizing a command like follows, It shouldn't be an issue.
powershell -command "((Get-date).AddDays(0)).ToString(':dd:MM:yyyy') | set-content 'captureVar.txt'" && set /p Yesterday=<captureVar.txt
It worked for the script I tested, but it's not thoroughly tested.
let me know how it goes.
I think the issue is more likely to be within "TheScriptToBeExecuted.ps1" than your bat. In fact several powershell command are working as Asyncronous.
I tested a Sleep-Start, which is not Asyncronous at all using the following code and the bat is waiting the end of it.
This is the code I used in my .bat
REM RUNTEST.BAT
time /T
echo started
powershell -executionpolicy remotesigned -File C:\Users\Alex\Desktop\DA_PROVARE\test.ps1
time /T
echo done
exit /b
The ps1 content is just one row, here below:
Start-Sleep -Seconds 25
The problem you are facing is probably because of the account under which the scheduler runs. Have faced similar problems where the .bat and/or .ps1 doesn't behave the same if launched by a scheduler or other tools
powershell -ExecutionPolicy ByPass -command ". 'C:\path\TheScriptToBeExecuted.ps1'"
This should do the it, if not then we will add < NUL to the end
powershell -ExecutionPolicy ByPass -command ". 'C:\path\TheScriptToBeExecuted.ps1'" < NUL
By using dot sourcing, we are opening powershell in the cmd window with the powershell reference in the above solution. Then the period allows the script to run in cmd window also. I did a double test and made a .ps1 with start-sleep -s 3 in it, and the above did wait for the powershell script to finish.
method 2
Using Start /wait
START /wait PowerShell.exe "& "'C:\path\TheScriptToBeExecuted.ps1'"
This method will not run inside the cmd window. It opens a powershell terminal and runs there then goes back to the bat.

Powershell / cmd - Redirecting embedded script's output streams to file

I have a situation in which a cmd script must launch a powershell script (install.ps1), elevating to admin if the cmd is not already. The line that launches the powershell looks like this:
powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass -File `\"%~dp0install.ps1`\" %args%\" -Verb runAs -Wait"
Or this also works:
powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass invoke-command { %~dp0install.ps1 %args% } \" -Verb runAs -Wait"
I would like to redirect the output from the install.ps1 script to a file for logging purposes, but having trouble doing this. Something like the following will generate the log.txt file, but output will still be shown in the console and the resulting log.txt file will be empty:
powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass invoke-command { %~dp0install.ps1 %args% } \" *> log.txt -Verb runAs -Wait"
Moving the *> log.txt portion to inside the Start-Process block (just after the invoke-command block), which I thought would be the key, seems to not even run the script at all (or it's flashing an error in the console too quick to see because it closes immediately).
Is it possible to achieve this logging behavior when the data I want is buried in a couple layers of powershell, executed by a cmd file?
We've technically gotten this to work by creating a powershell wrapper script that is called/elevated by the cmd, then within the wrapper calling the install.ps1 script and assigning logging in that call. Unfortunately the extra script layer causes a bunch of other tricky / more critical problems regarding getting arguments passed at the command line all the way through to the actual install script correctly, so we're really trying to avoid that route.
EDIT
Thanks to #mklement0 for the pointer that the redirect needed to be escaped, which was my problem. Follow-up question - The following command works great to log to file, but is there any way to get this same behavior using -File rather than -Command when invoking the PS script ("-Command %~dp0pg.ps1")?
powershell -Command "Start-Process -WindowStyle Hidden -Verb RunAs -Wait powershell \"-NoProfile -ExecutionPolicy Bypass -Command %~dp0pg.ps1 *^> %CD%\log.txt\""
Moving the *>log.txt redirection into the Invoke-Command block works in principle, but your problem is that in Windows PowerShell (as opposed to PowerShell Core) a process invoked with elevation (as admin), via -Verb RunAs, defaults to C:\Windows\System32 as the working directory, not the caller's working dir.
Aside from the fact that you probably didn't mean to create a log file in C:\Windows\System32, the command will fail, because writing to that location requires the caller to already be elevated.
The simplest solution is to make *> redirect to a file specified with a full path instead:
powershell -Command "Start-Process -WindowStyle Hidden -Verb RunAs -Wait powershell \"-NoProfile -ExecutionPolicy Bypass -Command %~dp0pg.ps1 *^> %CD%\log.txt\""
Note:
There is no need for Invoke-Command - just invoke the *.ps1 file directly; however, I've added -Command to make it more obvious that the remainder of the command line is to be interpreted as PowerShell code (not a script-file path with arguments only).
Because > is a cmd.exe metacharacter, it must be escaped as ^> in order to be passed through to PowerShell - perhaps surprisingly, cmd.exe considers the > to be unquoted, because it doesn't recognize the \" sequences as embedded double quotes - only PowerShell does.
As in your original command, the assumption is that neither %~dp0 - the batch file's folder dir. path - nor %CD% - the caller's working dir. path - contain spaces or other special chars. that would need additional quoting / escaping.

Why can't I tail a log in powershell when I run it from the run Window?

If I open a Power Shell window and run the following command it works fine...
get-content -Path C:\Users\user\AppData\Local\Temp\90\tmpDF49.tmp -wait
But if I open the run menu (WINKEY+R) and then run it like this:
powershell -command 'get-content -Path C:\Users\user\AppData\Local\Temp\90\tmpDF49.tmp -wait'
it opens a powershell window and then just closes...
I've also tried the same thing from a powershell script and it just closes up...just like with the run menu:
[Diagnostics.Process]::Start("powershell.exe", "-command `"get-content -Path $($tmpFile) -wait`"")
Shouldn't it keep waiting and trying to tail the log?
You need to run the following from the run line:
powershell -NoExit -command "Get-Content -Path C:\Users\user\AppData\Local\Temp\90\tmpDF49.tmp -wait"
The -command switch is designed to run the provided command and exit unless -NoExit is specified. -NoExit must come before the -command parameter by design as well.
Running PowerShell.exe -Help will divulge this information. I have been told that not all of the information is accurate, but the statements above appear to be.

Windows PowerShell to install NativeScript on Windows 10

I try to install NativeScript on Windows 10 from Admin PowerShell console.
https://docs.nativescript.org/start/ns-setup-win
I type this command and obtain the following error:
#powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://nativescript.org/setup/win-avd'))"
You're running the command from PowerShell when you need to run it from CMD command prompt.
Run this from CMD:
#powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://nativescript.org/setup/win-avd'))"
Here, #powershell means "don't echo the command and run powershell.exe". It means something completely different in PowerShell itself, where #powershell means "search the path and execute a program with the literal name #powershell before the extension" or "use the variable $powershell as a splat variable" depending on your PowerShell version.
If you're running it in Powershell, you'll need to run just:
iex ((new-object net.webclient).DownloadString('https://nativescript.org/setup/win-avd'))
As always, be extremely careful about running these commands that download arbitrary code and execute it immediately.