Executing a powershell script through batch file

I am trying to execute a powershell script through a batch file, at the moment I am only testing this to get it running so the .ps1 file is simply a hello world script.

This ALMOST works fine except there is a spanner to throw into the works;

I am trying to have the .ps1 stored in a remote location (on a shared NAS to be specific). This works when I have the .ps1 saved locally and point the .bat to the local .ps1.

However now that the .ps1 is in the remote location I am thrown with the following error;

"file (pathname) cannot be loaded. The file (pathname) is not digitally signed. The script will not execute on the system"

Now I am aware of execution policies and mine are as follows;

MachinePolicy = RemoteSigned
UserPolicy = Undefined
Process = Undefined
CurrentUser = RemoteSigned
LocalMachine = Bypass

I have tried changing CurrentUser to Bypass but I am thrown with the following;

Windows Powershell updated your execution policy successfully, but the setting is overridden by a policy defined at a more specific scope

Screenshot of above error

Any ideas would be greatly appreciated!

Sorry if this has been a lot of information! If any of it is unclear feel free to ask me to clarify! I'm fairly new to all of this!

1

8 Answers

You can still run the script - you just need to tell PowerShell to bypass the system's executionpolicy like this:

powershell.exe -executionpolicy bypass -file \\server\share\yourscript.ps1

I think the GroupPolicy configured by the company is enforcing the policy to revoke any execution of script from the remote location. Kindly check the Group Policy in the Administrative tools.

2

The other answer might actually be the answer, but in case you (or anyone else) is looking for a workaround, here it is.

In your batchfile, first copy the .ps1 file to a local folder, such as C:\TEMP, and then execute it by using start c:\temp\My_Script.ps1

The command start will make the script work the same way as double clicking it from explorer. You might not actually need to copy it locally if you used a different way to start the file.

2

For the .bat only aspect, a work around would be to make a .bat file that used echo statements to build a local powershell script, then execute the local script

How practical this would be would depend on how complex the script needed to be

This is what I use:

Standard Powershell, no admin elevation:

PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File ""c:\your\file\path\PSscript.ps1""'}"

Prompting for admin credentials:

PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File ""c:\your\file\path\PSscript.ps1""' -Verb RunAs}"

Posted it also here:

Following this thread:

you can convert any PowerShell script into a batch file easily using this PowerShell function:

function Convert-PowerShellToBatch
{ param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string] [Alias("FullName")] $Path ) process { $encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8))) $newPath = [Io.Path]::ChangeExtension($Path, ".bat") "@echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii }
}


To convert all PowerShell scripts inside a directory, simply run the following command:

Get-ChildItem -Path <DIR-PATH> -Filter *.ps1 | Convert-PowerShellToBatch

Where is the path to the desired folder. For instance:

Get-ChildItem -Path "C:\path\to\powershell\scripts" -Filter *.ps1 | Convert-PowerShellToBatch


To convert a single PowerShell script, simply run this:

Get-ChildItem -Path <FILE-PATH> | Convert-PowerShellToBatch

Where is the path to the desired file.

The converted files are located in the source directory. i.e., <FILE-PATH> or <DIR-PATH>.

Elyasaf755, Thank you very much. I turned your converter into a batch file, onto which multiple ps1 files can be simultaneously dropped to convert to batch, or it can be clicked upon to convert all psi files in the current folder.

REM POWERSHELL TO BATCH CONVERTER
REM DRAG & DROP ONE OR MULTIPLE POWERSHELL FILES ONTO THIS BATCH,
REM OR CLICK ON IT TO CONVERT ALL POWERSHELL SCRIPTS IN THE FOLDER
REM AND THEIR BATCH VERSIONS WILL BE CREATED IN THE SAME DIRECTORY
if [%1]==[] goto :CLICKED
:loop
SET INPUT=%1
if [%1]==[] goto :EOF
:DROPPED
REM COPIES ALL LINES FROM THIS BATCH WHICH DO NOT HAVE "A1B2XZ" IN THEM TO "ZZZZZAMA.TXT"
if not exist "ZZZZZAMA.TXT" FINDSTR /V /L /I /C:"A1B2XZ" "%~0">> "ZZZZZAMA.TXT"
REM "X_VARIABLE_X" STANDS FOR THE PATH TO THE FILE YOU DRAGGED & DROPPED
REM "X_VARIABLE_X" GETS REPLACED WITH THE REAL PATH FROM "%INPUT%"
SET "search="X_VARIABLE_X""
SET "replace=%INPUT%"
SET "File=ZZZZZAMA.TXT"
SET "Destination=ZZZZZAMA2.TXT"
setlocal DisableDelayedExpansion
for /F "TOKENS=* EOL= delims= " %%a in ('"findstr /n ^^ "%File%""') DO ( set "line=%%a" setlocal EnableDelayedExpansion set "line=!line:*:=!"
REM IF THE LINE IS BLANK IN THE INPUT, IT WRITES A BLANK LINE TO THE OUTPUT FILE if [!line!]==[] ( echo.>> "!Destination!"
REM IF THE LINE IS NOT BLANK IN THE INPUT, IT WRITES THE LINE TO THE OUTPUT FILE
REM REPLACING YOUR SEARCH WORD, IF IT EXISTS, WITH THE REPLACE WORD ) else ( echo(!line:%search%=%replace%!>> "!Destination!" ) endlocal
)
REM CTEATES "CONVERTER.PS1" FROM A PORTION OF TEXT IN "ZZZZZAMA2.TXT"
REM NOTE: A1B2XZ MUST STAY IN THE FOUR LINES BELOW
ECHO($config = Get-Content "ZZZZZAMA2.TXT" -Raw>> "YMCA.PS1" & REM A1B2XZ
ECHO( if ("$config" -Match '(?ms)YOUR_TEXT_BELOW_ME(.*?)YOUR_TEXT_ABOVE_ME') {>> "YMCA.PS1" & REM A1B2XZ
ECHO( $matches[1].Trim() ^| Set-Content 'CONVERTER.PS1'}>> "YMCA.PS1" & REM A1B2XZ
powershell -NoProfile -ExecutionPolicy Bypass -File "YMCA.ps1" & DEL /Q /F "YMCA.ps1" & REM A1B2XZ
REM SKIPS THE BLOCK POWERSHELL SCRIPT BELOW WHICH HAS ALREADY BEEN MADE INTO A FILE
goto :MoveOn
REM DO NOT REMOVE THE LINE BELOW [ BEGIN OF POWERSHELL SCRIPT "CONVERTER.ps1" ]
YOUR_TEXT_BELOW_ME
## POWERSHELL TO BATCH CONVERTER
## AS THIS SCRIPT IS AUTOMATED, DO NOT WRITE YOUR PATH AT THE BOTTOM
## AND IT WILL CREATE THE BATCH IN THE SAME DIRECTORY
function Convert-PowerShellToBatch
{ param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string] [Alias("FullName")] $Path ) process { $encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8))) $newPath = [Io.Path]::ChangeExtension($Path, ".bat") "@echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii }
}
Get-ChildItem -Path "X_VARIABLE_X" | Convert-PowerShellToBatch
YOUR_TEXT_ABOVE_ME
REM DO NOT REMOVE THE LINE ABOVE [ END OF POWERSHELL SCRIPT "CONVERTER.ps1" ]
:MoveOn
REM IT RUNS THE POWERSHELL SCRIPT NAMED "CONVERTER.ps1" TO CONVERT YOUR FILE
powershell -NoProfile -ExecutionPolicy Bypass -File "CONVERTER.ps1"
REM THE FILES BELOW MUST BE DELETED FOR THE SEQUENCE IN THIS SCRIPT TO WORK
del /f /q "CONVERTER.ps1"
del /f /q "ZZZZZAMA2.TXT"
REM THE TWO LINES BELOW PROVIDE THE LOOP FOR MULTIPLE FILES DRAGGED & DROPPED
shift
if not [%1]==[] goto loop
EXIT
:CLICKED
REM COPIES ALL LINES FROM THIS BATCH WHICH DO NOT HAVE "A1B22XZ" IN THEM TO "ZZZZZAMA3.TXT"
if not exist "ZZZZZAMA3.TXT" FINDSTR /V /L /I /C:"A1B22XZ" "%~0">> "ZZZZZAMA3.TXT"
REM CTEATES "CONVERTER3.PS1" FROM A PORTION OF TEXT IN "ZZZZZAMA3.TXT"
REM NOTE: A1B22XZ MUST STAY IN THE FOUR LINES BELOW - AN EXTRA 2 WAS ADDED
ECHO($config = Get-Content "ZZZZZAMA3.TXT" -Raw>> "YMCA3.PS1" & REM A1B22XZ
ECHO( if ("$config" -Match '(?ms)WRITE_UNDER_ME(.*?)WRITE_ON_TOP_OF_ME') {>> "YMCA3.PS1" & REM A1B22XZ
ECHO( $matches[1].Trim() ^| Set-Content 'CONVERTER3.PS1'}>> "YMCA3.PS1" & REM A1B22XZ
powershell -NoProfile -ExecutionPolicy Bypass -File "YMCA3.ps1" & DEL /Q /F "YMCA3.ps1" & REM A1B22XZ
REM SKIPS THE BLOCK POWERSHELL SCRIPT BELOW WHICH HAS ALREADY BEEN MADE INTO A FILE
goto :MoveOn3
REM DO NOT REMOVE THE LINE BELOW [ BEGIN OF POWERSHELL SCRIPT "CONVERTER3.ps1" ]
WRITE_UNDER_ME
## POWERSHELL TO BATCH CONVERTER
## AS THIS SCRIPT IS AUTOMATED, DO NOT WRITE YOUR PATH AT THE BOTTOM
## AND IT WILL CREATE THE BATCH IN THE SAME DIRECTORY
function Convert-PowerShellToBatch
{ param ( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string] [Alias("FullName")] $Path ) process { $encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content -Path $Path -Raw -Encoding UTF8))) $newPath = [Io.Path]::ChangeExtension($Path, ".bat") "@echo off`npowershell.exe -NoExit -encodedCommand $encoded" | Set-Content -Path $newPath -Encoding Ascii }
}
Get-ChildItem -Path "." -Filter *.ps1 | Convert-PowerShellToBatch
WRITE_ON_TOP_OF_ME
REM DO NOT REMOVE THE LINE ABOVE [ END OF POWERSHELL SCRIPT "CONVERTER3.ps1" ]
:MoveOn3
REM IT RUNS THE POWERSHELL SCRIPT NAMED "CONVERTER3.ps1" TO CONVERT YOUR FILE
powershell -NoProfile -ExecutionPolicy Bypass -File "CONVERTER3.ps1"
REM THE FILES BELOW GET DELETED
del /f /q "CONVERTER3.ps1"
del /f /q "ZZZZZAMA3.TXT"
del /f /q "CONVERTER3.BAT"
EXIT
____________________ END OF THE BATCH ABOVE __________________
BELOW ARE TWO BATCH HERESTRING SCRIPTS WHICH ARE EXACTLY THE SAME,
BUT ONE IS A MULTI-LINER AND THE OTHER A ONE-LINER:
REM _____________ HERESTRING - BATCH MULTI-LINER _____________
REM EXTRACTS TEXT BETWEEN TWO SEARCH PATTERNS = STRINGS OR LINES.
REM USE IT TO EMBED A POWERSHELL SCRIPT INTO A BATCH, OR ADAPT
REM THE EXTENSIONS & LAUNCHER ACCORDINGLY TO EMBED A VBSCRIPT.
REM NOTE: A PIPE "|" HAS BEEN ESCAPED AS "^|".
REM \s+ ENSURES THAT ONLY THE SEARCH PATTERNS FOLLOWED
REM BY SPACE ARE FOUND, THUS SKIPPING THE COMMAND LINE.
REM THE SEARCH PATTERNS, ESCAPED HERE WITH BRACKETS, ARE:
REM [YOUR_TEXT_BELOW_ME] & [YOUR_TEXT_ABOVE_ME].
SETLOCAL ENABLEDELAYEDEXPANSION & SET "SOURCE=%~0"
ECHO.$config = Get-Content "!SOURCE!" -Raw>> "TTTT.ps1"
ECHO.if ("$config" -Match '(?ms)YOUR_TEXT_BELOW_ME\s+(.*?)YOUR_TEXT_ABOVE_ME\s+') {>> "TTTT.ps1"
ECHO.$matches[1].Trim() ^| Set-Content 'YOUR_TEXT.ps1'}>> "TTTT.ps1"
powershell -NoProfile -ExecutionPolicy Bypass -File "TTTT.ps1" & "YOUR_TEXT.ps1"
del /f /q "TTTT.ps1" "YOUR_TEXT.ps1" & ENDLOCAL & goto :MoveOn & YOUR_TEXT_BELOW_ME YOUR TEXT HERE
YOUR_TEXT_ABOVE_ME & DO NOT REMOVE THIS LINE
:MoveOn
EXIT
OR
REM _____________ HERESTRING - BATCH ONE-LINER _____________
SETLOCAL ENABLEDELAYEDEXPANSION & SET "SOURCE=%~0" & ECHO.$config = Get-Content "!SOURCE!" -Raw; if ("$config" -Match '(?ms)YOUR_TEXT_BELOW_ME\s+(.*?)YOUR_TEXT_ABOVE_ME\s+') {$matches[1].Trim() ^| Set-Content 'YOUR_TEXT.ps1'}>> "TTTT.ps1" & powershell -NoProfile -ExecutionPolicy Bypass -File "TTTT.ps1" & "YOUR_TEXT.ps1" & del /f /q "TTTT.ps1" "YOUR_TEXT.ps1" & ENDLOCAL & goto :MoveOn & YOUR_TEXT_BELOW_ME YOUR TEXT HERE
YOUR_TEXT_ABOVE_ME & DO NOT REMOVE THIS LINE
:MoveOn
EXIT 

From what I've gathered in my own explorations of the topic, batch (or cmd) does not work with network locations. Additionally, from what I can see in your first post, you skipped some parts of the set-executionpolicy cmdlet.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like