Powershell Script only opens as a .txt file when run - powershell

Hi I have a script on a memory stick that I want to be able to run in cmd line before a computer has windows fully installed. (the stage just after you've connected to a network).
Cmd used to run the script.
Start > Run D:\pscript\Intune.ps1
This only opens a .txt file, while researching I've found that the reason this happens is due to security, is there anyway to override this bar changing the default file type out.

Unlike batch files (.cmd, .bat) associated with cmd.exe (the legacy Command Prompt), PowerShell's .ps1 script files are by default not directly executable from outside PowerShell.
Instead, they are treated as documents that are by default associated with either Notepad or the (obsolescent) Windows PowerShell ISE, depending on the , and invoking them therefore opens them for editing, which applies to the following contexts:
Invoking a .ps1 file from cmd.exe
Invoking a .ps1 file from Start Menu's Run dialog, as in your case (which you can invoke with WinKey+R, for instance)
Opening (double-clicking) a .ps1 file from File Explorer or Desktop.
To execute a .ps1 script from outside PowerShell, you must therefore invoke it via PowerShell's CLI, powershell.exe for Windows PowerShell, pwsh for PowerShell (Core) 7+.
In the simplest case, using Windows PowerShell and the -File parameter, as also shown by Mathias R. Jessen in a comment; see the comments below and the linked docs for additional parameters:
# Note:
# * The effective execution policy applies; use -ExecutionPolicy Bypass to bypass.
# * Profiles are loaded; use -NoProfile to suppress.
# * The console window auto-closes when the script terminates; use -NoExit
# to keep the session open.
powershell.exe -File D:\pscript\Intune.ps1
For a comprehensive overview of PowerShell's CLI, see this post.
It is possible - though not advisable - to configure your system to execute .ps1 files by default - see this answer.

Related

Format PS1 to be Double-Clicked [duplicate]

I have my_project.ps1 file from which I am activating virtual environment & starting my project.
currently I need to open my powershell then after I need to go to directory where I have saved my .ps1 file & have to open it from powershell only.
Is there any way so that I can double click on .ps1 file & it will open automatically in power shell ?
By design, double-clicking (opening) *.ps1 files from the Windows [GUI] shell (in this case: Desktop, File Explorer, and the taskbar, via pinned items) does not execute them - instead they're opened for editing in Notepad or in the PowerShell ISE, depending on the Windows / PowerShell version.
However, since at least Windows 7, the shortcut menu for *.ps1 files contains a Run with PowerShell command, which does invoke the script at hand; this may be enough for your purposes, but this invocation method has limitations - see the bottom section for details.
If you do want to redefine double-clicking / opening so that it executes *.ps1 scripts, you have two options:
Note:
For a given script (as opposed to all .ps1 files), you may alternatively create a shortcut file or batch file that launches it, but that isn't a general solution, as you'd have to create a companion file for each and every .ps1 file you want to run by double-clicking. It does, however, give you full control over the invocation. You can create shortcut files interactively, via File Explorer, as described in this answer, or programmatically, as shown in this answer. Similarly, you may create a companion batch file (.cmd or .bat) that invokes your script, because batch file are executed when double-clicked; e.g., if you place a batch file with the same base name as your .ps1 script in the same directory (e.g., foo.cmd next to foo.ps1), you can call it from your batch file as follows; -NoExit keeps the session open:
#powershell.exe -NoExit -File "%~dpn0.ps1" %*
The methods below also enable direct execution of a .ps1 script from a cmd.exe console window, synchronously, inside the same window. In other words: You can execute, say, script foo.ps1 directly as such, instead of having to use the PowerShell CLI, say, powershell.exe -File foo.ps1
[Not recommended] GUI method:
Use File Explorer to make PowerShell execute .ps1 files by default:
Right-click on a .ps1 file and select Properties.
Click on Change... next to the Opens with: label.
Click on More apps on the bottom of the list and scroll down to Look for another app on this PC
Browse to or paste file path C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe and submit.
This method gives you no control over the specifics of the PowerShell invocation and has major limitations; in effect you'll end up with the following behavior:
Major limitations:
Script paths with embedded spaces and ' chars. cannot be invoked this way, because, even though such paths are passed with double quotes, the latter are in effect stripped by PowerShell, because the path is passed to the implied -Command parameter, which first strips (unescaped) double quotes from the command line before interpreting the result as PowerShell code - in which case paths with spaces are seen as multiple arguments / paths that contain (an odd number of) ' cause a syntax error.
Note that if you were to select pwsh.exe instead, the CLI of the cross-platform, install-on-demand PowerShell (Core) 7+ edition, that problem would not arise, because it defaults to the -File parameter - in which case a double-quoted script-file path is properly recognized.
For the difference between PowerShell CLI calls using -Command vs. those using -File, see this answer.
Passing arguments is not supported, which matters if you want to invoke .ps1 files directly from cmd.exe and need to pass arguments.
The redefinition is only in effect for the current user - which is probably a good thing, as other users may not expect this change, which can result in unwanted execution of scripts.
Whatever execution policy is in effect will be honored; e.g., if Restricted is in effect, invocation will fail altogether.
As with the default Run in PowerShell command, the window in which the script runs will automatically close when the script ends - thus, unless the script explicitly prompts the user before exiting, you may not be able to examine its output.
To exercise more control over how PowerShell invokes the script including support for paths with spaces and for passing arguments, use the programmatic method shown in the next section.
Programmatic method:
Important:
The GUI method overrides a programmatic solution, so it must be removed - the code below does this automatically.
Unfortunately, there's another, accidental override that can happen if you have Visual Studio Code installed: Whenever you use File Explorer's shortcut menu to open a file in Visual Studio Code, it unexpectedly becomes the default action. The code below detects this condition and fixes the problem, but it will resurface the next time a .ps1 file is opened this way.
Modify the registry to redefine the Open shortcut-menu command for *.ps1 files at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\Open\Command, as shown below.
You can run the code as-is to create a user-level file-type definition that:
uses the executable that runs the current PowerShell session, i.e. powershell.exe in Windows PowerShell, and pwsh.exe in PowerShell (Core) 7+.
respects the effective execution policy - add an -ExecutionPolicy argument to override.
loads the profiles first - add -NoProfile to suppress loading; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer, in combination with not using -NoExit.
runs in the script in its own directory
keeps the session open after the script exits - remove -NoExit to exit the session when the script ends; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer.
If you requirements differ - if you need different CLI parameters and /or you want to use pwsh.exe, i.e. PowerShell (Core) 7+ instead - tweak the code first, by modifying the $cmd = ... line below; see the comments above it.
# Specify if the change should apply to the CURRENT USER only, or to ALL users.
# NOTE: If you set this to $true - which is NOT ADVISABLE -
# you'll need to run this code ELEVATED (as administrator)
$forAllUsers = $false
# Determine the chosen scope's target registry key path.
$targetKey = "$(('HKCU', 'HKLM')[$forAllUsers]):\Software\Classes\Microsoft.PowerShellScript.1\shell\Open\Command"
# In the user-specific hive (HKCU: == HKEY_CURRENT_USER), the target key
# doesn't exist by default (whereas it does in the local-machine hive (HLKM: == HKEY_LOCAL_MACHINE)),
# so we need to make sure that it exists.
if (-not $forAllUsers -and -not (Test-Path -LiteralPath $targetKey)) {
$null = New-Item -Path $targetKey -Force -ErrorAction Stop
}
# Specify the command to use when opening / double-clicking *.ps1 scripts:
# As written here:
# * The script runs in the directory in which it resides.
# * The profiles are loaded (add -NoProfile to change).
# * The current execution policy is respected (add -ExecutionPolicy <policy> to override, if possible)
# * The window stays open after the script exits (remove -NoExit to change)
# For help with all parameters, see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
$cmd = "`"$((Get-Process -Id $PID).Path)`" -nologo -noexit -file `"%1`" %*"
# Write the command to the registry.
Set-ItemProperty -ErrorAction Stop -LiteralPath $targetKey -Name '(default)' -Value $cmd
Write-Verbose -Verbose "$(('User-level', 'Machine-level')[$forAllUsers]) file-type definition for *.ps1 files successfully updated."
# Additionally, make sure that NO OVERRIDES preempt the new definition.
# See if a user override established interactively via File Explorer happens to be defined,
# and remove it, if so.
if ($fileExplorerOverrideKey = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\UserChoice') {
Write-Verbose -Verbose 'Removing File Explorer override...'
# Get the parent key path and the key name
$parentKeyPath = $fileExplorerOverrideKey.PSParentPath -replace '^.+?::\w+\\' # Remove the 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\' prefix
$keyName = $fileExplorerOverrideKey.PSChildName
$key = $null
try {
# Open the *parent* key for writing.
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubkey($parentKeyPath, $true)
# Delete the subkey.
# !! Due to the specific permissions assigned by File Explorer to the key
# !! (an additional DENY access-control entry for the current user, for the key itself only, for the 'Set Value' permission),
# !! using the .DeleteSubKey*Tree*() method fails (Remove-Item implicitly uses this method and therefore fails too)
# !! However, since there should be no nested subkeys, using .DeleteSubkey() should work fine.
$key.DeleteSubKey($keyName)
}
catch {
throw
}
finally {
if ($key) { $key.Close()}
}
}
# See if *Visual Studio Code* was most recently used to open a *.ps1 file:
# If so, it inexplicably OVERRIDES a file-type definition.
# (This doesn't seem to happen with other executables.)
# !! We fix the problem, but it will RESURFACE the next time File Explorer's shortcut menu
# !! is used to open a *.ps1 file in Visual Studio Code.
if ($itm = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\OpenWithList') {
if (($names = $itm.GetValueNames().Where({ $itm.GetValue($_) -ceq 'Code.exe' })) -and ($mruList = $itm.GetValue('MRUList')) -and $mruList[0] -in $names) {
Write-Warning "Visual Studio Code was most recently used to open a .ps1 file, which unexpectedly overrides the file-type definition.`nCorrecting the problem for now, but it will resurface the next time you use File Explorer's shortcut menu to open a .ps1 file in Visual Studio Code."
# Note: Normally there aren't, but there *can* be *multiple* Code.exe entries, namely after manual removal of the MRUList:
# The next time you choose to open in VSCode via File Explorer's shortcut menu, an *additional* Code.exe entry is added.
do { # Trim the start of the MRUList until its first entry no longer references Code.exe
$mruList = $mruList.Substring(1)
} while ($mruList[0] -in $names)
# Update the MRUList value in the registry.
$itm | Set-ItemProperty -Name 'MRUList' -Value $mruList
}
}
Explanation of the predefined Run in PowerShell shortcut-menu command:
It is defined in registry key HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\0\Command (as of Windows 10) as follows:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1'"
This command is flawed in that it breaks with script-file paths that happen to contain ' characters.
Unless execution policy AllSigned is in effect - in which case only signed scripts can be executed but are executed without prompting - the command attempts to set the execution policy for the invoked process to Bypass, which means that any script can be executed, but only after the user responds to a confirmation prompt beforehand (irrespective of whether the script is signed or not, and whether it was downloaded from the web or not).
At least in earlier Windows 7 releases / PowerShell versions, the command was misdefined[1] in a way that effectively ignored the attempt to set the process' execution policy, which meant that whatever execution policy was persistently configured applied - and no confirmation prompt was shown.
Unless the targeted script explicitly pauses to wait for user input before exiting, the window in which the script will close automatically when the script finishes, so you may not get to see its output.
The targeted script executes in the directory in which it is located as the working directory (current location)
[1] The earlier, broken command definition was "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" "-Command" "if((Get-ExecutionPolicy ) -ne AllSigned) { Set-ExecutionPolicy -Scope Process Bypass }", which meant what anything after -file "%1" was passed as arguments to file "%1" instead of the intended execution of the commands following -Command; additionally - a moot point - the AllSigned operand would have need to be quoted.
To execute a PS1 file by double-click (to run)
Make a shortcut for the file and set the target to this:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "C:\Temp\MyPowershellScript.ps1"
Replace the second directory (the one in quotes) with the location of your script.
To read a PS1 file by double-click (to edit)
Same as above, but target ISE instead, as that will force it into edit mode.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe "C:\Temp\MyPowershellScript.ps1"
Server 2012 and newer by default do not associate the .PS1 file extension with the PowerShell executable; rather, they default to open .PS1 files with notepad by default for security reasons.
If you have access, you need to change the file association through the 'default programs' in your control panel for the .PS1 files to execute by double clicking.
Also be aware that you may have to change your execution policy to get particular scripts to run.
Also, as it sounds like this script might be a core automation, you can execute scripts from in another one with either of these, without the need to change the active working directory:
Invoke-Item ""
& ''
I have fixed the registry values so that the .ps1 scripts are executed with double click or with "Run with PowerShell" from any position without problem, even with paths with multiple consecutive spaces and with apostrophes:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.ps1]
#="Microsoft.PowerShellScript.1"
[HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Drive\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\",0"
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\Edit\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe\" -File \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell]
"ExecutionPolicy"="RemoteSigned"

Powershell script executes correctly when I choose "run with powershell", but not when I "open with" powershell or double-click it [duplicate]

I have my_project.ps1 file from which I am activating virtual environment & starting my project.
currently I need to open my powershell then after I need to go to directory where I have saved my .ps1 file & have to open it from powershell only.
Is there any way so that I can double click on .ps1 file & it will open automatically in power shell ?
By design, double-clicking (opening) *.ps1 files from the Windows [GUI] shell (in this case: Desktop, File Explorer, and the taskbar, via pinned items) does not execute them - instead they're opened for editing in Notepad or in the PowerShell ISE, depending on the Windows / PowerShell version.
However, since at least Windows 7, the shortcut menu for *.ps1 files contains a Run with PowerShell command, which does invoke the script at hand; this may be enough for your purposes, but this invocation method has limitations - see the bottom section for details.
If you do want to redefine double-clicking / opening so that it executes *.ps1 scripts, you have two options:
Note:
For a given script (as opposed to all .ps1 files), you may alternatively create a shortcut file or batch file that launches it, but that isn't a general solution, as you'd have to create a companion file for each and every .ps1 file you want to run by double-clicking. It does, however, give you full control over the invocation. You can create shortcut files interactively, via File Explorer, as described in this answer, or programmatically, as shown in this answer. Similarly, you may create a companion batch file (.cmd or .bat) that invokes your script, because batch file are executed when double-clicked; e.g., if you place a batch file with the same base name as your .ps1 script in the same directory (e.g., foo.cmd next to foo.ps1), you can call it from your batch file as follows; -NoExit keeps the session open:
#powershell.exe -NoExit -File "%~dpn0.ps1" %*
The methods below also enable direct execution of a .ps1 script from a cmd.exe console window, synchronously, inside the same window. In other words: You can execute, say, script foo.ps1 directly as such, instead of having to use the PowerShell CLI, say, powershell.exe -File foo.ps1
[Not recommended] GUI method:
Use File Explorer to make PowerShell execute .ps1 files by default:
Right-click on a .ps1 file and select Properties.
Click on Change... next to the Opens with: label.
Click on More apps on the bottom of the list and scroll down to Look for another app on this PC
Browse to or paste file path C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe and submit.
This method gives you no control over the specifics of the PowerShell invocation and has major limitations; in effect you'll end up with the following behavior:
Major limitations:
Script paths with embedded spaces and ' chars. cannot be invoked this way, because, even though such paths are passed with double quotes, the latter are in effect stripped by PowerShell, because the path is passed to the implied -Command parameter, which first strips (unescaped) double quotes from the command line before interpreting the result as PowerShell code - in which case paths with spaces are seen as multiple arguments / paths that contain (an odd number of) ' cause a syntax error.
Note that if you were to select pwsh.exe instead, the CLI of the cross-platform, install-on-demand PowerShell (Core) 7+ edition, that problem would not arise, because it defaults to the -File parameter - in which case a double-quoted script-file path is properly recognized.
For the difference between PowerShell CLI calls using -Command vs. those using -File, see this answer.
Passing arguments is not supported, which matters if you want to invoke .ps1 files directly from cmd.exe and need to pass arguments.
The redefinition is only in effect for the current user - which is probably a good thing, as other users may not expect this change, which can result in unwanted execution of scripts.
Whatever execution policy is in effect will be honored; e.g., if Restricted is in effect, invocation will fail altogether.
As with the default Run in PowerShell command, the window in which the script runs will automatically close when the script ends - thus, unless the script explicitly prompts the user before exiting, you may not be able to examine its output.
To exercise more control over how PowerShell invokes the script including support for paths with spaces and for passing arguments, use the programmatic method shown in the next section.
Programmatic method:
Important:
The GUI method overrides a programmatic solution, so it must be removed - the code below does this automatically.
Unfortunately, there's another, accidental override that can happen if you have Visual Studio Code installed: Whenever you use File Explorer's shortcut menu to open a file in Visual Studio Code, it unexpectedly becomes the default action. The code below detects this condition and fixes the problem, but it will resurface the next time a .ps1 file is opened this way.
Modify the registry to redefine the Open shortcut-menu command for *.ps1 files at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\Open\Command, as shown below.
You can run the code as-is to create a user-level file-type definition that:
uses the executable that runs the current PowerShell session, i.e. powershell.exe in Windows PowerShell, and pwsh.exe in PowerShell (Core) 7+.
respects the effective execution policy - add an -ExecutionPolicy argument to override.
loads the profiles first - add -NoProfile to suppress loading; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer, in combination with not using -NoExit.
runs in the script in its own directory
keeps the session open after the script exits - remove -NoExit to exit the session when the script ends; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer.
If you requirements differ - if you need different CLI parameters and /or you want to use pwsh.exe, i.e. PowerShell (Core) 7+ instead - tweak the code first, by modifying the $cmd = ... line below; see the comments above it.
# Specify if the change should apply to the CURRENT USER only, or to ALL users.
# NOTE: If you set this to $true - which is NOT ADVISABLE -
# you'll need to run this code ELEVATED (as administrator)
$forAllUsers = $false
# Determine the chosen scope's target registry key path.
$targetKey = "$(('HKCU', 'HKLM')[$forAllUsers]):\Software\Classes\Microsoft.PowerShellScript.1\shell\Open\Command"
# In the user-specific hive (HKCU: == HKEY_CURRENT_USER), the target key
# doesn't exist by default (whereas it does in the local-machine hive (HLKM: == HKEY_LOCAL_MACHINE)),
# so we need to make sure that it exists.
if (-not $forAllUsers -and -not (Test-Path -LiteralPath $targetKey)) {
$null = New-Item -Path $targetKey -Force -ErrorAction Stop
}
# Specify the command to use when opening / double-clicking *.ps1 scripts:
# As written here:
# * The script runs in the directory in which it resides.
# * The profiles are loaded (add -NoProfile to change).
# * The current execution policy is respected (add -ExecutionPolicy <policy> to override, if possible)
# * The window stays open after the script exits (remove -NoExit to change)
# For help with all parameters, see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
$cmd = "`"$((Get-Process -Id $PID).Path)`" -nologo -noexit -file `"%1`" %*"
# Write the command to the registry.
Set-ItemProperty -ErrorAction Stop -LiteralPath $targetKey -Name '(default)' -Value $cmd
Write-Verbose -Verbose "$(('User-level', 'Machine-level')[$forAllUsers]) file-type definition for *.ps1 files successfully updated."
# Additionally, make sure that NO OVERRIDES preempt the new definition.
# See if a user override established interactively via File Explorer happens to be defined,
# and remove it, if so.
if ($fileExplorerOverrideKey = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\UserChoice') {
Write-Verbose -Verbose 'Removing File Explorer override...'
# Get the parent key path and the key name
$parentKeyPath = $fileExplorerOverrideKey.PSParentPath -replace '^.+?::\w+\\' # Remove the 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\' prefix
$keyName = $fileExplorerOverrideKey.PSChildName
$key = $null
try {
# Open the *parent* key for writing.
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubkey($parentKeyPath, $true)
# Delete the subkey.
# !! Due to the specific permissions assigned by File Explorer to the key
# !! (an additional DENY access-control entry for the current user, for the key itself only, for the 'Set Value' permission),
# !! using the .DeleteSubKey*Tree*() method fails (Remove-Item implicitly uses this method and therefore fails too)
# !! However, since there should be no nested subkeys, using .DeleteSubkey() should work fine.
$key.DeleteSubKey($keyName)
}
catch {
throw
}
finally {
if ($key) { $key.Close()}
}
}
# See if *Visual Studio Code* was most recently used to open a *.ps1 file:
# If so, it inexplicably OVERRIDES a file-type definition.
# (This doesn't seem to happen with other executables.)
# !! We fix the problem, but it will RESURFACE the next time File Explorer's shortcut menu
# !! is used to open a *.ps1 file in Visual Studio Code.
if ($itm = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\OpenWithList') {
if (($names = $itm.GetValueNames().Where({ $itm.GetValue($_) -ceq 'Code.exe' })) -and ($mruList = $itm.GetValue('MRUList')) -and $mruList[0] -in $names) {
Write-Warning "Visual Studio Code was most recently used to open a .ps1 file, which unexpectedly overrides the file-type definition.`nCorrecting the problem for now, but it will resurface the next time you use File Explorer's shortcut menu to open a .ps1 file in Visual Studio Code."
# Note: Normally there aren't, but there *can* be *multiple* Code.exe entries, namely after manual removal of the MRUList:
# The next time you choose to open in VSCode via File Explorer's shortcut menu, an *additional* Code.exe entry is added.
do { # Trim the start of the MRUList until its first entry no longer references Code.exe
$mruList = $mruList.Substring(1)
} while ($mruList[0] -in $names)
# Update the MRUList value in the registry.
$itm | Set-ItemProperty -Name 'MRUList' -Value $mruList
}
}
Explanation of the predefined Run in PowerShell shortcut-menu command:
It is defined in registry key HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\0\Command (as of Windows 10) as follows:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1'"
This command is flawed in that it breaks with script-file paths that happen to contain ' characters.
Unless execution policy AllSigned is in effect - in which case only signed scripts can be executed but are executed without prompting - the command attempts to set the execution policy for the invoked process to Bypass, which means that any script can be executed, but only after the user responds to a confirmation prompt beforehand (irrespective of whether the script is signed or not, and whether it was downloaded from the web or not).
At least in earlier Windows 7 releases / PowerShell versions, the command was misdefined[1] in a way that effectively ignored the attempt to set the process' execution policy, which meant that whatever execution policy was persistently configured applied - and no confirmation prompt was shown.
Unless the targeted script explicitly pauses to wait for user input before exiting, the window in which the script will close automatically when the script finishes, so you may not get to see its output.
The targeted script executes in the directory in which it is located as the working directory (current location)
[1] The earlier, broken command definition was "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" "-Command" "if((Get-ExecutionPolicy ) -ne AllSigned) { Set-ExecutionPolicy -Scope Process Bypass }", which meant what anything after -file "%1" was passed as arguments to file "%1" instead of the intended execution of the commands following -Command; additionally - a moot point - the AllSigned operand would have need to be quoted.
To execute a PS1 file by double-click (to run)
Make a shortcut for the file and set the target to this:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "C:\Temp\MyPowershellScript.ps1"
Replace the second directory (the one in quotes) with the location of your script.
To read a PS1 file by double-click (to edit)
Same as above, but target ISE instead, as that will force it into edit mode.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe "C:\Temp\MyPowershellScript.ps1"
Server 2012 and newer by default do not associate the .PS1 file extension with the PowerShell executable; rather, they default to open .PS1 files with notepad by default for security reasons.
If you have access, you need to change the file association through the 'default programs' in your control panel for the .PS1 files to execute by double clicking.
Also be aware that you may have to change your execution policy to get particular scripts to run.
Also, as it sounds like this script might be a core automation, you can execute scripts from in another one with either of these, without the need to change the active working directory:
Invoke-Item ""
& ''
I have fixed the registry values so that the .ps1 scripts are executed with double click or with "Run with PowerShell" from any position without problem, even with paths with multiple consecutive spaces and with apostrophes:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.ps1]
#="Microsoft.PowerShellScript.1"
[HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Drive\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\",0"
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\Edit\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe\" -File \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell]
"ExecutionPolicy"="RemoteSigned"

Any way to double-click on .PS1 file & open them in PowerShell?

I have my_project.ps1 file from which I am activating virtual environment & starting my project.
currently I need to open my powershell then after I need to go to directory where I have saved my .ps1 file & have to open it from powershell only.
Is there any way so that I can double click on .ps1 file & it will open automatically in power shell ?
By design, double-clicking (opening) *.ps1 files from the Windows [GUI] shell (in this case: Desktop, File Explorer, and the taskbar, via pinned items) does not execute them - instead they're opened for editing in Notepad or in the PowerShell ISE, depending on the Windows / PowerShell version.
However, since at least Windows 7, the shortcut menu for *.ps1 files contains a Run with PowerShell command, which does invoke the script at hand; this may be enough for your purposes, but this invocation method has limitations - see the bottom section for details.
If you do want to redefine double-clicking / opening so that it executes *.ps1 scripts, you have two options:
Note:
For a given script (as opposed to all .ps1 files), you may alternatively create a shortcut file or batch file that launches it, but that isn't a general solution, as you'd have to create a companion file for each and every .ps1 file you want to run by double-clicking. It does, however, give you full control over the invocation. You can create shortcut files interactively, via File Explorer, as described in this answer, or programmatically, as shown in this answer. Similarly, you may create a companion batch file (.cmd or .bat) that invokes your script, because batch file are executed when double-clicked; e.g., if you place a batch file with the same base name as your .ps1 script in the same directory (e.g., foo.cmd next to foo.ps1), you can call it from your batch file as follows; -NoExit keeps the session open:
#powershell.exe -NoExit -File "%~dpn0.ps1" %*
The methods below also enable direct execution of a .ps1 script from a cmd.exe console window, synchronously, inside the same window. In other words: You can execute, say, script foo.ps1 directly as such, instead of having to use the PowerShell CLI, say, powershell.exe -File foo.ps1
[Not recommended] GUI method:
Use File Explorer to make PowerShell execute .ps1 files by default:
Right-click on a .ps1 file and select Properties.
Click on Change... next to the Opens with: label.
Click on More apps on the bottom of the list and scroll down to Look for another app on this PC
Browse to or paste file path C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe and submit.
This method gives you no control over the specifics of the PowerShell invocation and has major limitations; in effect you'll end up with the following behavior:
Major limitations:
Script paths with embedded spaces and ' chars. cannot be invoked this way, because, even though such paths are passed with double quotes, the latter are in effect stripped by PowerShell, because the path is passed to the implied -Command parameter, which first strips (unescaped) double quotes from the command line before interpreting the result as PowerShell code - in which case paths with spaces are seen as multiple arguments / paths that contain (an odd number of) ' cause a syntax error.
Note that if you were to select pwsh.exe instead, the CLI of the cross-platform, install-on-demand PowerShell (Core) 7+ edition, that problem would not arise, because it defaults to the -File parameter - in which case a double-quoted script-file path is properly recognized.
For the difference between PowerShell CLI calls using -Command vs. those using -File, see this answer.
Passing arguments is not supported, which matters if you want to invoke .ps1 files directly from cmd.exe and need to pass arguments.
The redefinition is only in effect for the current user - which is probably a good thing, as other users may not expect this change, which can result in unwanted execution of scripts.
Whatever execution policy is in effect will be honored; e.g., if Restricted is in effect, invocation will fail altogether.
As with the default Run in PowerShell command, the window in which the script runs will automatically close when the script ends - thus, unless the script explicitly prompts the user before exiting, you may not be able to examine its output.
To exercise more control over how PowerShell invokes the script including support for paths with spaces and for passing arguments, use the programmatic method shown in the next section.
Programmatic method:
Important:
The GUI method overrides a programmatic solution, so it must be removed - the code below does this automatically.
Unfortunately, there's another, accidental override that can happen if you have Visual Studio Code installed: Whenever you use File Explorer's shortcut menu to open a file in Visual Studio Code, it unexpectedly becomes the default action. The code below detects this condition and fixes the problem, but it will resurface the next time a .ps1 file is opened this way.
Modify the registry to redefine the Open shortcut-menu command for *.ps1 files at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\Open\Command, as shown below.
You can run the code as-is to create a user-level file-type definition that:
uses the executable that runs the current PowerShell session, i.e. powershell.exe in Windows PowerShell, and pwsh.exe in PowerShell (Core) 7+.
respects the effective execution policy - add an -ExecutionPolicy argument to override.
loads the profiles first - add -NoProfile to suppress loading; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer, in combination with not using -NoExit.
runs in the script in its own directory
keeps the session open after the script exits - remove -NoExit to exit the session when the script ends; this is primarily of interest if you're planning to directly invoke .ps1 files from cmd.exe, not (just) from File Explorer.
If you requirements differ - if you need different CLI parameters and /or you want to use pwsh.exe, i.e. PowerShell (Core) 7+ instead - tweak the code first, by modifying the $cmd = ... line below; see the comments above it.
# Specify if the change should apply to the CURRENT USER only, or to ALL users.
# NOTE: If you set this to $true - which is NOT ADVISABLE -
# you'll need to run this code ELEVATED (as administrator)
$forAllUsers = $false
# Determine the chosen scope's target registry key path.
$targetKey = "$(('HKCU', 'HKLM')[$forAllUsers]):\Software\Classes\Microsoft.PowerShellScript.1\shell\Open\Command"
# In the user-specific hive (HKCU: == HKEY_CURRENT_USER), the target key
# doesn't exist by default (whereas it does in the local-machine hive (HLKM: == HKEY_LOCAL_MACHINE)),
# so we need to make sure that it exists.
if (-not $forAllUsers -and -not (Test-Path -LiteralPath $targetKey)) {
$null = New-Item -Path $targetKey -Force -ErrorAction Stop
}
# Specify the command to use when opening / double-clicking *.ps1 scripts:
# As written here:
# * The script runs in the directory in which it resides.
# * The profiles are loaded (add -NoProfile to change).
# * The current execution policy is respected (add -ExecutionPolicy <policy> to override, if possible)
# * The window stays open after the script exits (remove -NoExit to change)
# For help with all parameters, see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
$cmd = "`"$((Get-Process -Id $PID).Path)`" -nologo -noexit -file `"%1`" %*"
# Write the command to the registry.
Set-ItemProperty -ErrorAction Stop -LiteralPath $targetKey -Name '(default)' -Value $cmd
Write-Verbose -Verbose "$(('User-level', 'Machine-level')[$forAllUsers]) file-type definition for *.ps1 files successfully updated."
# Additionally, make sure that NO OVERRIDES preempt the new definition.
# See if a user override established interactively via File Explorer happens to be defined,
# and remove it, if so.
if ($fileExplorerOverrideKey = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\UserChoice') {
Write-Verbose -Verbose 'Removing File Explorer override...'
# Get the parent key path and the key name
$parentKeyPath = $fileExplorerOverrideKey.PSParentPath -replace '^.+?::\w+\\' # Remove the 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\' prefix
$keyName = $fileExplorerOverrideKey.PSChildName
$key = $null
try {
# Open the *parent* key for writing.
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubkey($parentKeyPath, $true)
# Delete the subkey.
# !! Due to the specific permissions assigned by File Explorer to the key
# !! (an additional DENY access-control entry for the current user, for the key itself only, for the 'Set Value' permission),
# !! using the .DeleteSubKey*Tree*() method fails (Remove-Item implicitly uses this method and therefore fails too)
# !! However, since there should be no nested subkeys, using .DeleteSubkey() should work fine.
$key.DeleteSubKey($keyName)
}
catch {
throw
}
finally {
if ($key) { $key.Close()}
}
}
# See if *Visual Studio Code* was most recently used to open a *.ps1 file:
# If so, it inexplicably OVERRIDES a file-type definition.
# (This doesn't seem to happen with other executables.)
# !! We fix the problem, but it will RESURFACE the next time File Explorer's shortcut menu
# !! is used to open a *.ps1 file in Visual Studio Code.
if ($itm = Get-Item -ErrorAction Ignore -LiteralPath 'registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\OpenWithList') {
if (($names = $itm.GetValueNames().Where({ $itm.GetValue($_) -ceq 'Code.exe' })) -and ($mruList = $itm.GetValue('MRUList')) -and $mruList[0] -in $names) {
Write-Warning "Visual Studio Code was most recently used to open a .ps1 file, which unexpectedly overrides the file-type definition.`nCorrecting the problem for now, but it will resurface the next time you use File Explorer's shortcut menu to open a .ps1 file in Visual Studio Code."
# Note: Normally there aren't, but there *can* be *multiple* Code.exe entries, namely after manual removal of the MRUList:
# The next time you choose to open in VSCode via File Explorer's shortcut menu, an *additional* Code.exe entry is added.
do { # Trim the start of the MRUList until its first entry no longer references Code.exe
$mruList = $mruList.Substring(1)
} while ($mruList[0] -in $names)
# Update the MRUList value in the registry.
$itm | Set-ItemProperty -Name 'MRUList' -Value $mruList
}
}
Explanation of the predefined Run in PowerShell shortcut-menu command:
It is defined in registry key HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\0\Command (as of Windows 10) as follows:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1'"
This command is flawed in that it breaks with script-file paths that happen to contain ' characters.
Unless execution policy AllSigned is in effect - in which case only signed scripts can be executed but are executed without prompting - the command attempts to set the execution policy for the invoked process to Bypass, which means that any script can be executed, but only after the user responds to a confirmation prompt beforehand (irrespective of whether the script is signed or not, and whether it was downloaded from the web or not).
At least in earlier Windows 7 releases / PowerShell versions, the command was misdefined[1] in a way that effectively ignored the attempt to set the process' execution policy, which meant that whatever execution policy was persistently configured applied - and no confirmation prompt was shown.
Unless the targeted script explicitly pauses to wait for user input before exiting, the window in which the script will close automatically when the script finishes, so you may not get to see its output.
The targeted script executes in the directory in which it is located as the working directory (current location)
[1] The earlier, broken command definition was "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" "-Command" "if((Get-ExecutionPolicy ) -ne AllSigned) { Set-ExecutionPolicy -Scope Process Bypass }", which meant what anything after -file "%1" was passed as arguments to file "%1" instead of the intended execution of the commands following -Command; additionally - a moot point - the AllSigned operand would have need to be quoted.
To execute a PS1 file by double-click (to run)
Make a shortcut for the file and set the target to this:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "C:\Temp\MyPowershellScript.ps1"
Replace the second directory (the one in quotes) with the location of your script.
To read a PS1 file by double-click (to edit)
Same as above, but target ISE instead, as that will force it into edit mode.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe "C:\Temp\MyPowershellScript.ps1"
Server 2012 and newer by default do not associate the .PS1 file extension with the PowerShell executable; rather, they default to open .PS1 files with notepad by default for security reasons.
If you have access, you need to change the file association through the 'default programs' in your control panel for the .PS1 files to execute by double clicking.
Also be aware that you may have to change your execution policy to get particular scripts to run.
Also, as it sounds like this script might be a core automation, you can execute scripts from in another one with either of these, without the need to change the active working directory:
Invoke-Item ""
& ''
I have fixed the registry values so that the .ps1 scripts are executed with double click or with "Run with PowerShell" from any position without problem, even with paths with multiple consecutive spaces and with apostrophes:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.ps1]
#="Microsoft.PowerShellScript.1"
[HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Drive\shell\Powershell\command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\\"\""
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\",0"
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -File \"%1\""
[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\Edit\Command]
#="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe\" -File \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell]
"ExecutionPolicy"="RemoteSigned"

Execute batch file in Powershell

I want to execute the following from a batch file:
"C:\OpenCover\tools\OpenCover.Console.exe" -register:user -target:"%VS110COMNTOOLS%..\IDE\mstest.exe" -targetargs:"/testcontainer:\"C:\Develop\bin\Debug\MyUnitTests.dll\" ... "
PAUSE
Now I would like to log the output of the process to a file for which I came across the quite handy powershell usage of
powershell "dir | tee output.log"
but this does not take my batch file as first argument (powershell "my.bat | tee output.log") because it is not the name of a cmdlet or a function or a script file.
I could change my batch file so that is says powershell "OpenCover.Console.exe..." but I would have to adapt all quotes and change escape characters and so forth.
Is there a way to make a batch file execute in powershell? Or is there a way to drop in my line unchanged from the batch after some powershell command and it all executes "like it ought to"?
Unless your batch file is in a folder in the %PATH%, PowerShell won't find it [1], so you'll have to supply an explicit file path (whether relative or absolute).
For instance, if the batch file is in the current folder, run:
powershell -c ".\my.bat | tee output.log"
Consider adding -noprofile to suppress loading of the profile files, which is typically only needed in interactive sessions.
If your batch file path contains embedded spaces, enclose it in single quotes and prepend &:
powershell -c "& '.\my script.bat' | tee output.log"
Note: I've deliberately added the -c (short for: -Command) parameter name above; while powershell.exe - Windows PowerShell - defaults to this parameter, that is no longer true in PowerShell [Core] v6+ (whose executable name is pwsh), where -File is now the default - see about_PowerShell.exe and about_pwsh
[1] More accurately, PowerShell - unlike cmd.exe - will by design not execute scripts in the current folder by their mere filename (in an interactive PowerShell session you'll get a hint to that effect). This is a security feature designed to prevent accidental invocation of a different executable than intended.
Unless you have some purpose for doing so not stated in the OP, there isn't a reason to use both Powershell and a batch script. If you want to do this solely from PS, you can create a PS script that does everything the batch file does.
To avoid the escaping issues (or alternatively to take advantage of CMD.EXE's somewhat strange escaping behavior :-) you can use --%, introduced in PS 3.0. It is documented under about_escape_characters.

Set up PowerShell Script for Automatic Execution

I have a few lines of PowerShell code that I would like to use as an automated script. The way I would like it to be able to work is to be able to call it using one of the following options:
One command line that opens PowerShell, executes script and closes PowerShell (this would be used for a global build-routine)
A file that I can double-click to run the above (I would use this method when manually testing components of my build process)
I have been going through PowerShell documentation online, and although I can find lots of scripts, I have been unable to find instructions on how to do what I need. Thanks for the help.
From http://blogs.msdn.com/b/jaybaz_ms/archive/2007/04/26/powershell-polyglot.aspx
If you're willing to sully your beautiful PowerShell script with a little CMD, you can use a PowerShell-CMD polyglot trick. Save your PowerShell script as a .CMD file, and put this line at the top:
#PowerShell -ExecutionPolicy Bypass -Command Invoke-Expression $('$args=#(^&{$args} %*);'+[String]::Join(';',(Get-Content '%~f0') -notmatch '^^#PowerShell.*EOF$')) & goto :EOF
If you need to support quoted arguments, there's a longer version, which also allows comments. (note the unusual CMD commenting trick of double #).
##:: This prolog allows a PowerShell script to be embedded in a .CMD file.
##:: Any non-PowerShell content must be preceeded by "##"
##setlocal
##set POWERSHELL_BAT_ARGS=%*
##if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
##PowerShell -ExecutionPolicy Bypass -Command Invoke-Expression $('$args=#(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join(';',$((Get-Content '%~f0') -notmatch '^^##'))) & goto :EOF
Save your script as a .ps1 file and launch it using powershell.exe, like this:
powershell.exe .\foo.ps1
Make sure you specify the full path to the script, and make sure you have set your execution policy level to at least "RemoteSigned" so that unsigned local scripts can be run.
Run Script Automatically From Another Script (e.g. Batch File)
As Matt Hamilton suggested, simply create your PowerShell .ps1 script and call it using:
PowerShell C:\Path\To\YourPowerShellScript.ps1
or if your batch file's working directory is the same directory that the PowerShell script is in, you can use a relative path:
PowerShell .\YourPowerShellScript.ps1
And before this will work you will need to set the PC's Execution Policy, which I show how to do down below.
Run Script Manually Method 1
You can see my blog post for more information, but essentially create your PowerShell .ps1 script file to do what you want, and then create a .cmd batch file in the same directory and use the following for the file's contents:
#ECHO OFF
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%MyPowerShellScript.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'"
Replacing MyPowerShellScript.ps1 on the 3rd line with the file name of your PowerShell script.
This will allow you to simply double click the batch file to run your PowerShell script, and will avoid you having to change your PowerShell Execution Policy.
My blog post also shows how to run the PowerShell script as an admin if that is something you need to do.
Run Script Manually Method 2
Alternatively, if you don't want to create a batch file for each of your PowerShell scripts, you can change the default PowerShell script behavior from Edit to Run, allowing you to double-click your .ps1 files to run them.
There is an additional registry setting that you will want to modify so that you can run scripts whose file path contains spaces. I show how to do both of these things on this blog post.
With this method however, you will first need to set your execution policy to allow scripts to be ran. You only need to do this once per PC and it can be done by running this line in a PowerShell command prompt.
Start-Process PowerShell -ArgumentList 'Set-ExecutionPolicy RemoteSigned -Force' -Verb RunAs
Set-ExecutionPolicy RemoteSigned -Force is the command that actually changes the execution policy; this sets it to RemoteSigned, so you can change that to something else if you need. Also, this line will automatically run PowerShell as an admin for you, which is required in order to change the execution policy.
Source for Matt's answer.
I can get it to run by double-clicking a file by creating a batch file with the following in it:
C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe LocationOfPS1File
you can use this command :
powershell.exe -argument c:\scriptPath\Script.ps1