2

The execution policy in my environment is AllSigned:

PS E:\Temp> Get-ExecutionPolicy
AllSigned

When I try to execute a not trusted script it throws the error:

& : File C:\temp\anz.ps1 cannot be loaded. The file C:\temp\any.ps1 is not
digitally signed.
You cannot run this script on the current system. For more information about
running scripts and setting execution policy, see about_Execution_Policies at
http://go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:3
+ & .\any.ps1
+   ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : SecurityError: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

How can I make PowerShell prompt me for whether I want to execute the script or not?

Something like:

Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful this script can potentially harm your computer. Do you want to run .\temp.ps1?
[D] Do not run [R] Run Once [S] Suspent:

Note: I do not want to bypass or supress the prompt.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Jay Joshi
  • 1,402
  • 1
  • 13
  • 32
  • 2
    There's only limited options for execution policies, see [about_execution_policies](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies). You can't build custom policies, so you have to choose the option that is best fit for you. – henrycarteruk Jun 12 '18 at 11:07
  • 3
    Note that having a digital signature doesn't make a script safe. "I want to choose whether to run this script downloaded from the Internet" isn't the same thing as "I want to choose to run this unsigned script". Downloaded scripts can be signed, and scripts created locally may be unsigned. Detecting whether a file was downloaded is possible, though, as James mentioned, it's separate from the execution policy. – Jeroen Mostert Jun 12 '18 at 11:27
  • Thanks for the feedback, 1) I have seen some post about PowerShell prompting when the script is not signed : https://stackoverflow.com/questions/728143/ignore-security-warning-running-script-from-command-line 2) At the moment I have created a script which generates mentioned error in other machines. – Jay Joshi Jun 12 '18 at 12:01

2 Answers2

2

You could add a function to check the file first:

function Test-FileSafety {
    # This function simply returns $true when the file is ok or the user decided to
    # go ahead and run it even though he/she was warned.
    # If the user decided it was too tricky and bailed out, the function returns $false
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [ValidateScript({Test-Path $_ -PathType Leaf})] 
        [Alias ('Path')]
        [string]$FileName
    )

    Add-Type -AssemblyName System.Windows.Forms
    $letsGo = $true

    # first test if the file was downloaded from internet (and was not already unblocked)
    if (Get-Item $FileName -Stream zone*) {
        $message  = "Run only scripts that you trust.`r`n"
        $message += "While scripts from the Internet can be useful this script can potentially harm your computer.`r`n`r`n"
        $message += "Do you want to allow '$FileName' ?"

        $result = [System.Windows.Forms.MessageBox]::Show($message, "Security Warning", 3)
        # evaluate the users response and act upon it
        switch ($result) {
            Yes    { <# user wants to run #> Unblock-File -Path $FileName ; break }
            No     { <# user decided not to run the script #> ; $letsGo = $false; break }
            Cancel { <# user bailed out #> ; $letsGo = $false; break }
        }
    }

    # next test if the file is digitally signed or not
    if ($letsGo -and (Get-AuthenticodeSignature -FilePath $FileName).Status -eq 'NotSigned') {
        $message  = "Run only scripts that you trust.`r`n"
        $message += "The script is not digitally signed.`r`n`r`n"
        $message += "Do you still want to run '$FileName' ?"

        $result = [System.Windows.Forms.MessageBox]::Show($message, "Security Warning", 3)
        # evaluate the users response and act upon it
        switch ($result) {
            Yes    { <# user wants to run even though the script is not digitally signed #> ; break}
            No     { <# user decided it was too dangerous and does not want to run the script #> ; $letsGo = $false; break}
            Cancel { <# user bailed out #> ; $letsGo = $false; break}
        }
    }

    return $letsGo
}

and use it like:

if ((Test-FileSafety -FileName "C:\temp\anz.ps1")) {
    # run the script
}
else {
    # do nothing, the user cancelled
}
Theo
  • 57,719
  • 8
  • 24
  • 41
  • +1 for the answer and your efforts Theo. If I look at this from the customer's side, I just wanted to suggest some configuration to the customer instead of providing a Powershell script. (.. But again, it is my point of view...) Your approach also seems perfect. – Jay Joshi Jun 14 '18 at 06:19
1

You can try running the following command in power shell as an administrator

The fix is to run Set-ExecutionPolicy and change the Execution Policy setting.

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

 “Bypass” means nothing is blocked and no warnings, prompts, or messages will be displayed.

Timeless
  • 7,338
  • 9
  • 60
  • 94
Ragavan Rajan
  • 4,171
  • 1
  • 25
  • 43