Respondido Launching Powershell script "Out of the box" problems.

  • segunda-feira, 14 de maio de 2012 07:46
     
      Contém Código

    Hi!

    I have made a powershell script that requires administrative priviledges, and will most likely be ran from a usb memory stick, on a freshly installed Win 7 computer with no domain etc. So, to make running the script as small a problem it could be i made a batch file named "runme.bat" to start up the powershell script with unrestricted execution policy, like so:

    PowerShell.exe -ExecutionPolicy Bypass -File %CD%/psfile.ps1

    Works fine, it always find the Powershell script and it runs by just doubleclicking the .bat file. Now we dont have to open up powershell and change the execution policy, Great!

    However, This script("psfile.ps1") requires Administrative priviledges. And when you run batch scripts as an administrator, the variable %CD% becomes useless as it changes to the system32 folder. So now i cant, in an easy way, find my Powershell script. So i did some research and found another technet topic concerning the issue. they suggested that one should put:

    runas /noprofile /user:localhost\administrator cmd

    In the beginning of the script.

    However, since the script will be used on a Win 7 "out of the box" the local administrator account is disabled. So we wont be able to use it since it needs the local administrator account to be used.

    So im stuck in a bind. I want to be able to run my powershell script with as little overhead as possible. right click  > run as administrator would be preferable if it can be done.

    Anyone have any ideas? Can you call an UAC prompt from powershell? is there a way we could copy the psfile.ps1 to system32 so it will run when using "right click > run as administrator" and no runas line?

Todas as Respostas

  • segunda-feira, 14 de maio de 2012 09:17
     
     

    How about adding a line in your script that copies the script to an environment variable such as %temp% and execute the script from there? %TEMP% should be available to you when you elevate your script.



    Jaap Brasser
    http://www.jaapbrasser.com

  • segunda-feira, 14 de maio de 2012 14:00
    Moderador
     
      Contém Código

    Hi,

    You can test for elevation inside the PowerShell script itself. If the script is not running elevated, you can instruct to run elevated. For example:

    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    $elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
    
    if (-not $elevated) {
      write-host -nonewline "You must run this script elevated. Press ENTER to continue: "
      read-host
    }
    

    Bill


  • terça-feira, 15 de maio de 2012 09:14
     
     

    I've tought about this, but how would i find the script in the first place? it might be on E: or Z: or \\fileserver\

    I guess you could do a search for it, but i would have to be made in batch. Any ideas?

    It will most likely be ran from a thumbdrive.

  • terça-feira, 15 de maio de 2012 09:17
     
      Contém Código

    Hi,

    You can test for elevation inside the PowerShell script itself. If the script is not running elevated, you can instruct to run elevated. For example:

    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    $elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
    
    if (-not $elevated) {
      write-host -nonewline "You must run this script elevated. Press ENTER to continue: "
      read-host
    }
    

    Bill


    That is not enough, it asks for elevation but since we cant run the powershell script by just clicking it when windows 7 is "Out of the box" it doesnt really help. I want to make it as easy as possible to run. And requiring the user to go and boot up powershell, change the execution policy and then run the script is what im trying to avoid.

    I want it to be as easy as "right click file > run as administrator"

  • terça-feira, 15 de maio de 2012 12:20
     
      Contém Código

    Hi,

    You can test for elevation inside the PowerShell script itself. If the script is not running elevated, you can instruct to run elevated. For example:

    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    $elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
    
    if (-not $elevated) {
      write-host -nonewline "You must run this script elevated. Press ENTER to continue: "
      read-host
    }
    

    Bill


    That is not enough, it asks for elevation but since we cant run the powershell script by just clicking it when windows 7 is "Out of the box" it doesnt really help. I want to make it as easy as possible to run. And requiring the user to go and boot up powershell, change the execution policy and then run the script is what im trying to avoid.

    I want it to be as easy as "right click file > run as administrator"

    Unfortunately Windows is desighned that way.  YOu cannot undo what has been designed in - 'Out-of-the-Box'

    The question you are asking indicates that you are probably trying to do something that should not be done the way you are trying to do it.  Post the task you are trying to accomplish and we can probably help you.

    Why would a notma; user need to be able to launch as an administrator with no indication that this is the case.

    What you have outlined would not work on any version of Windows ever.


    ¯\_(ツ)_/¯

  • terça-feira, 15 de maio de 2012 13:48
    Moderador
     
     

    Hi,

    You could use the elevate32.exe (or elevate64.exe) utility available on my site to run your PowerShell script. It's a small utility that lets you run a program elevated. This can be used in a shell script (batch file) to launch an elevated process.

    Bill

  • terça-feira, 15 de maio de 2012 21:29
     
     
    I interpret your question into two parts:

    1) You need to bypass UAC to run the PS script.

    2) When you run the script with elavated privilege, you lose the ability to use local environment variables.

    Now from what you said I assume the intention to use %CD% is based on a relative location between the script and the calling batch file.  Unfortunately that variable is credential dependent.

    The solution is to use batch parameters.  If the script is in a location relative to the batch file, %~dp0 will give you the complete path to the parent folder of the batch file, from which you can construct the path to the script. 

    Bypassing UAC is a tricky business, so far the only 'out of the box' way I found is to use Task Scheduler, with 'Run with highest privileges' selected.  Configure it so that it allows run on demand to suit your situation.
  • terça-feira, 15 de maio de 2012 21:33
    Moderador
     
     

    Hi,

    FWIW, it didn't seem like he was looking for a way to bypass the UAC prompt but rather how to programmatically trigger it to make things easier for the admin launching the script. Your second reference is good with regards to expanded batch parameter syntax, though.

    Bill

  • terça-feira, 15 de maio de 2012 21:43
     
     

    Can you address the issue that you(all) are using 'elevated' in the same context as 'alternate' credentials.  They are different.

    A standard user using 'RunAs' with admin credentials -  this is not 'Elevated' it is 'Alternate'. 

    "Elevated" means to gain all rights not enabled due to UAC. 

    Two completely different issues and two completely different solutions.

    Which one is the OP having an issue with?


    ¯\_(ツ)_/¯

  • terça-feira, 15 de maio de 2012 21:48
     
     

    I want it to be as easy as "right click file > run as administrator"

    Have you tried creating a shortcut to the batch file with Run as Administrator selected?


  • terça-feira, 15 de maio de 2012 21:51
    Moderador
     
     

    Hi,

    The runas verb triggers an elevation prompt if the current user is a member of Administrators but not running elevated, and it triggers a prompt for administrative credentials if the current user is not a member of Administrators.

    Bill

  • terça-feira, 15 de maio de 2012 21:56
    Moderador
     
     
    Have you tried creating a shortcut to the batch file with Run as Administrator selected?

    That's not as convenient as having the batch file (shell script) itself generate the UAC prompt. Hence elevate32.exe/elevate64.exe.

    Bill

  • terça-feira, 15 de maio de 2012 21:57
     
     

    Still requires user intervention but in case of stabdard user admin credentials need to be entered.  If we docorate the shortcut with /u:administrator then only a password need be entered.

    I still don't understand waht the original question is actually asking for.

    If the %CD% ariable is in teh users sessoin then elevation would not erase this.  If the %CD% variable was just created at a prompt then it would not be available in the elevated session.

    If the link was on the USB then the %CD% varaible would be unnecessary as it would refer to the current drive/folder.

    There is not enough information to provide a useful answer.


    ¯\_(ツ)_/¯

  • terça-feira, 15 de maio de 2012 22:42
     
      Contém Código

    This is a self elevation batch, it's not a UAC bypass!

    The code part after the :Elevated label will be executed only if the user has the UAC Rights Elevation , with this batch you don't need  Run as Administrator because UAC prompt is automatically triggered.

    Bye Gas

    @echo off
    TITLE Self-elevation-Batch & mode con:cols=100 lines=50 & COLOR 17 
    :: Self Elevation Batch
    :: self-ele.cmd
    :: by Gastone Canali
    set no-output=2^>nul ^>NUL 
    
    set CD=C:\Users\g\Documents\WindowsPowerShell
    
    :checkPerm
    whoami /groups|find /i "BUILTIN\Administrators" %no-output%|| goto :_ERR 
    set TestFile="%windir%\checkPerm%random%" 
    set Elevation="%temp%\elevation.vbs" 
    mkdir %TestFile% 2>nul 1>nul && (rmdir /q %TestFile% & goto :Elevated) 
    echo waiting for become elevated ... 
    >  %Elevation% echo Set UAC = CreateObject^("Shell.Application"^) 
    >> %Elevation% echo UAC.ShellExecute %0, "", "", "runas", 1
    cscript //nologo //B "%temp%\Elevation.vbs"
    exit /B
    
    :Elevated 
    if exist %Elevation% del /Q %Elevation% %no-output%
    echo Now we are elevated&echo.
    set cd
    echo PowerShell.exe -ExecutionPolicy Bypass -File %CD%/psfile.ps1
    echo.
    set /p pause= Press any key to continue...
    
    PowerShell.exe -ExecutionPolicy Bypass -File %CD%/psfile.ps1
    
    
    goto :EOF
    
    :_ERR
    echo ERR: No Admin permission ... 
    
    


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!

  • quarta-feira, 16 de maio de 2012 03:35
    Moderador
     
     

    Hi,

    That's a cool script -- but I would point out that it won't work if:

    1. The local Administrators group has a different name (different language)
    2. The user has permission (for some reason) to write to %windir%

    Otherwise -- clever!

    Bill

  • quarta-feira, 16 de maio de 2012 15:13
    Moderador
     
     Respondido Contém Código

    Here is an example of a shell script (.cmd batch file) that uses Elevate64.exe to run a PowerShell script elevated:

    @echo off
    setlocal enableextensions
    set SCRIPTPATH=%~dp0
    "%SCRIPTPATH%Elevate64.exe" -- ^
    %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe ^
    -ExecutionPolicy Bypass -File "%SCRIPTPATH%PowerShellScript.ps1"
    endlocal
    

    You would put Elevate64.exe (or Elevate32.exe if you have 32-bit OS) and the PowerShell script in the same directory as the above .cmd script. Double-click on the .cmd script from Explorer and it will run the PowerShell script using elevated permissions.

    Bill


  • quarta-feira, 16 de maio de 2012 19:03
     
      Contém Código

    Hi,That's a cool script -- but I would point out that it won't work if:

    1. The local Administrators group has a different name (different language)
    2. The user has permission (for some reason) to write to %windir%

    Otherwise -- clever!
    Bill

    Thanks Bill, I changed the script, so the Achilles' heel is only the point two.

    Bye Gas

    @echo off
    TITLE Self-elevation-Batch & mode con:cols=100 lines=50 & COLOR 17 
    :: Self Elevation Batch
    :: self-ele.cmd
    :: by Gastone Canali
    set no-output=2^>nul ^>NUL 
    
    set CD=C:\Users\g\Documents\WindowsPowerShell
    
    :checkPerm
    
    set TestFile="%windir%\checkPerm%random%" 
    set Elevation="%temp%\elevation.vbs" 
    mkdir %TestFile% 2>nul 1>nul && (rmdir /q %TestFile% & goto :Elevated) 
    echo waiting for become elevated ... 
    >  %Elevation% echo Set UAC = CreateObject^("Shell.Application"^) 
    >> %Elevation% echo UAC.ShellExecute %0, "", "", "runas", 1
    cscript //nologo //B "%temp%\Elevation.vbs"
    exit /B
    
    :Elevated 
    if exist %Elevation% del /Q %Elevation% %no-output%
    echo Now we are elevated&echo.
    set cd
    echo PowerShell.exe -ExecutionPolicy Bypass -File %CD%/psfile.ps1
    echo.
    set /p pause= Press any key to continue...
    
    PowerShell.exe -ExecutionPolicy Bypass -File %CD%/psfile.ps1
    
    
    goto :EOF
    
    :_ERR
    echo ERR: No Admin permission ... 
    


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!

  • quarta-feira, 16 de maio de 2012 19:33
    Moderador
     
     

    Cool. But can you do it in 7 lines (5 if I don't use ^ at the end of lines)? <grin> (Of course, my solution takes up a bit more disk space with the external executable.)

    Bill

  • quinta-feira, 17 de maio de 2012 23:52
     
     Respondido Contém Código

    Hi Bill, this is 4 lines without the need to use an external executable and no need to change it if SO is x32 or x64 (this is the thinner version of the my precedent post)

    @echo off
    set CD=c:\temp
    >  "%temp%\ele.vbs" echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "PowerShell.exe", " -ExecutionPolicy Bypass -File %CD%\PowerShellScript.ps1", "", "runas", 1
    cscript //nologo //B "%temp%\Ele.vbs"

    Bye Gas

    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!


  • quinta-feira, 17 de maio de 2012 23:59
     
      Contém Código

    The unreadable one line only :)

    @echo off &set CD=c:\temp&>  "%temp%\e.vbs" echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "PowerShell.exe", " -ExecutionPolicy Bypass -File %CD%\dirdir.ps1", "", "runas", 1&cscript //nologo //B "%temp%\e.vbs"


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!

  • sexta-feira, 18 de maio de 2012 00:00
    Moderador
     
     

    Hi Gastone,

    Not so fast :)

    What if c:\temp doesn't exist?

    Cool though!

    Bill

  • sexta-feira, 18 de maio de 2012 12:20
     
     Resposta Proposta Contém Código

    Hi Bill,

    Cool your freepascal elevate64.exe/elevate32.exe, but your batch solution arrived only one day after my post  :)

    About C:\temp ... it's like your script without any type of control!!  If  elevate64.exe doesn't exist?  If  elevate64.exe isn't in the correct path?  If PowerShellScript.ps1 isn't in %SCRIPTPATH%? ... (check the correctness need more lines then the elavation part... )

    But my preferred and very cool  script is this (http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/23/a-self-elevating-powershell-script.aspx):

    # Get the ID and security principal of the current user account
    $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
    $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
    
    # Get the security principal for the Administrator role
    $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
    
    # Check to see if we are currently running "as Administrator"
    if ($myWindowsPrincipal.IsInRole($adminRole))
       {
       # We are running "as Administrator" - so change the title and background color to indicate this
       $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
       $Host.UI.RawUI.BackgroundColor = "DarkBlue"
       clear-host
       }
    else
       {
       # We are not running "as Administrator" - so relaunch as administrator
       
       # Create a new process object that starts PowerShell
       $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
       
       # Specify the current script path and name as a parameter
       $newProcess.Arguments = $myInvocation.MyCommand.Definition;
       
       # Indicate that the process should be elevated
       $newProcess.Verb = "runas";
       
       # Start the new process
       [System.Diagnostics.Process]::Start($newProcess);
       
       # Exit from the current, unelevated, process
       exit
       }
    
    # Run your code that needs to be elevated here
    Write-Host -NoNewLine "Press any key to continue..."
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

    Bye Gas


    Gastone Canali >http://www.armadillo.it

    Se alcuni post rispondono al tuo quesito (non necessariamente i miei), ricorda di contrassegnarli come risposta e non dimenticare di contrassegnare anche i post utili . GRAZIE!


  • sexta-feira, 18 de maio de 2012 14:15
    Moderador
     
      Contém Código

    Hi Gastone,

    It's true that the .exe file is a prerequisite for the script and can be checked this way:

    if not exist "%SCRIPTPATH%elevate64.exe" ...

    or something similar.

    On another note: That blog posting looks rather similar to something I posted a while back:

    http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/c19ea16c-db8a-4b6a-bc14-09936f8ea8e3

    His posting predates mine, though :)

    I do like your idea of a dynamically generated VBScript that contains the shell runas command.

    Bill

  • sexta-feira, 25 de maio de 2012 15:15
    Moderador
     
     

    As there has been no activity in this thread for a few days, we assume the issue is resolved. We will mark it as "answered" to assist others in similar situations. If you disagree, please reply with further information. You can unmark the answer if you wish. If a reply helped answer your question, please mark it as the answer.


    Richard Mueller - MVP Directory Services