9

EDIT: To future readers, in short, PowerShell scripts weren't intended to be used this way which is why there is no elegant solution.

I have the following line which runs a script as an administrator from a shortcut:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -noexit Start-Process Powershell -verb RunAs -ArgumentList "C:\Documents\WindowsPowerShell\Scripts\test.ps1"

I want to change:

"C:\Documents\WindowsPowerShell\Scripts\test.ps1"

to a relative path like:

".\test.ps1"

but I haven't figured out how I can do that. How can I run the script relative to the location of the shortcut? (The shortcut and script are in the same folder)

9
  • possible duplicate of What's the best way to determine the location of the current PowerShell script? Commented Mar 18, 2014 at 21:14
  • Is this an actual shortcut like you would get by right-click-dragging and selecting Create Shortcuts Here? Or is this a batch file that launches your PowerShell script? Or is this being launched from Scheduled Tasks? Or other? Please be as explicit as possible. Commented Mar 18, 2014 at 22:19
  • @Entbark: Its and actual shortcut created by right-clicking and selecting create shortcuts here. Commented Mar 18, 2014 at 22:22
  • OK, then if you go into the shortcut properties, go to the Shortcut tab, and make sure that the value in Start In is the same as the location of your script. Try that. Commented Mar 19, 2014 at 17:31
  • 1
    @Entbark: Thanks for the help. Unfortunately, no matter what I try I cannot get it to work as you explain. I even copied exactly what is in your comment and still got the same error. noam's solution below however worked for me. Commented Mar 20, 2014 at 14:12

5 Answers 5

3

Here is an ugly workaround.

Shortcut.lnk file with Target: %COMSPEC% /C .\launcher.cmd (source) and Start In: %CD% (or blank).

Launcher.cmd file with contents:

Powershell -noprofile -noexit -File %CD%\PSlauncher.ps1

PSlauncher.ps1 file with contents:

Start-Process Powershell -verb RunAs -ArgumentList ($pwd.path + "\test.ps1")

Surely there is a better solution. Maybe with the -WorkingDirectory parameter of Start-Process? Or storing credentials with the Convert*-SecureString cmdlets? Count me curious.

Why do you want a shortcut?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks this solution works, but as you mentioned it is ugly. Basically I wanted an easy way to distribute scripts to people who know nothing about PowerShell. Looking around it seems packaging scripts into an exe or creating a gui would be the other solution.
Yeah. This looked good in a demo, but i haven't tried it. Of course it comes with a coffee maker and toaster oven you probably won't need...
2

After much trial and error, I've come up with a solution:

Create a shortcut with this (edited for your .ps1) to have scrips run as admin relative to any directory:

CMD /C PowerShell "SL -PSPath '%CD%'; $Path = (GL).Path; SL ~; Start PowerShell -Verb RunAs -Args \""SL -PSPath '"$Path"'; & '".\YourScriptHere.ps1"'"\""

You'll have to empty the shortcut's "Start in" field to have its relative path be set as the working directory.

Or, here's a script that will generate one of these shortcuts for each .ps1 in a directory (with "Start in" already cleared):

(GCI | Where-Object {$_.Extension -eq ".ps1"}).Name | ForEach-Object {
    $WshShell = New-Object -ComObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut((GL).Path+"\$_ Run.lnk")
    $Shortcut.TargetPath = 'CMD'
    $Shortcut.Arguments = "/C PowerShell `"SL -PSPath `'%CD%`'; `$Path = (GL).Path; SL ~; Start PowerShell -Verb RunAs -Args \`"`"SL -PSPath `'`"`$Path`"`'; & `'`".\$_`"`'`"\`"`""    
    $Shortcut.IconLocation = 'PowerShell.exe'
    $Shortcut.Save()
}

If needed, add -NoExit, -ExecutionPolicy Unrestricted, etc. just after the first \".

Notes:

The reason for a second, admin instance of PowerShell launching from the first, is that launching as admin directly (by ticking a shortcut's "Run as administrator" box), for some reason ignores "Start in" and always launches in System32.

CMD is being used to launch the first instance because PowerShell currently fails to resolve paths containing square brackets, interpreting them as regex characters. This would normally be avoided using the LiteralPath parameter (aka PSPath), but here, the path is being passed behind the scenes at launch, and it's up to the developers to fix (I just filed a bug report here).

1 Comment

If I need multiple parameters, it doesn't seem to work. E.g. CMD /C PowerShell "SL -PSPath '%CD%'; $Path = (GL).Path; SL ~; Start PowerShell -Verb RunAs -Args \"-ExecutionPolicy ByPass -WindowStyle Hidden" SL -PSPath '"$Path"'; & '".\DisconnectOnIdle.ps1"'"\""
0

When I run a script from a shortcut, it uses the path of the actual script. You can check the current directory with pwd (present working directory). You can check (and then use) the path of the script with split-path -parent $MyInvocation.MyCommand.Definition like the answer says in What's the best way to determine the location of the current PowerShell script?.

So to answer your question, you should already be able to use relative paths. Have you tried it? If so, what was your experience?

5 Comments

Can you show an example of the syntax I need to use?
Can you be more specific? Which part are you needing syntax for? You already seem to know how to use relative paths as demonstrated in your question.
Changing "C:\Documents\WindowsPowerShell\Scripts\test.ps1" to ".\test.ps1" and clicking the shortcut gives an error that it cannot recognize ".\test.ps1" as a cmdlet, executable, etc.
Here is another example C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -noexit -command "& Start-Process Powershell -verb RunAs .\test.ps1", this will cause an error when run from a shortcut that .\test.ps1 cannot be recognized.
How are you telling the script where to run from? Are you changing directories (cd) to it? Or are you specifying where to run from? If you don't specify the run-from location, it won't know you want it to run there.
0

For your script, set it to open using Powershell by default. Create a shortcut for your script and assign it a hot key by right clicking on your shortcut, selecting properties, click the shortcut tab. Move your cursor the select shortcut key and define a shortcut key. Each time you press the shortcut key your script will run

Comments

-1

This is definitely made out to be more difficult than it is.

This issue is more likely to affect you on Windows Server. On regular Windows, you can run Set-ExecutionPolicy unrestricted and it will stay in affect on the machine, on Windows Server (at least on AWS), setting the execution policy from a powershell script only lasts for the session of the script and it closes immediately so you can't see the error.

I just successfully modded the registry on an AWS instance bypassing group policy and can simply right click powershell scripts from any directory and send a shortcut to the desktop that is runnable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.