I am trying to write a script to push through datto to copy a shortcut to each endpoint's public desktop. UAC is getting in my way, and I'm trying to find a way around it.
So far I have tried this script which fails due to not having admin perms:
Function ShortcutCopy {
Copy-Item -Path "\\path\to\file" -Destination "C:\Users\Public\Desktop"
}
ShortcutCopy
Then I modified it to try to get it to run powershell as admin and run the command from the new instance, but it opens elevated powershell then immediately closes without actually copying the shortcut:
Function ShortcutCopy {
Copy-Item -Path "\\path\to\file" -Destination "C:\Users\Public\Desktop"
}
powershell -Command "Start-Process powershell -Verb RunAs -ArgumentList 'ShortcutCopy'"
The shortcut is located in a network share that is accessible. Is there a better way to write this?
A newly launched PowerShell process doesn't have access to functions defined on demand in the caller's scope, so your attempt to call your ShortcutCopy
function in the elevated child PowerShell session won't work.
You don't need a call to powershell.exe
, the Windows PowerShell CLI in addition to calling Start-Process
-Verb RunAs
- use only the latter.
Therefore:
Start-Process powershell.exe -Verb RunAs -ArgumentList @'
"Function ShortcutCopy {
Copy-Item -Path \"\\path\to\file\" -Destination \"C:\Users\Public\Desktop\"
}
ShortcutCopy"
'@
The above embeds the definition of the ShortcutCopy
function in the (implied) -Command
argument passed to the elevated powershell.exe
instance. You don't strictly need a function wrapper, though - you can use just the function's body in this case.
"
chars. that should be passed through as part of the code passed to the (implied) -Command
parameters must be \
-escaped. Additionally, to avoid potential whitespace normalization, the code is enclosed in "..."
overall.Once the function has finished executing, the elevated powershell.exe
process exits, as a result of which its window closes automatically.
For troubleshooting, you can place -NoExit
before Function ...
to keep the elevated session alive and therefore the window open.
To examine the exit code of the elevated process programmatically, pass -PassThru
and -Wait
to Start-Process
, capture the resulting process-information object, and query its .ExitCode
property.