Powershell helper for fast & reliable 360° panorama waypoint missions

Hi everyone,

I wanted to share a PowerShell script I’ve been working on that might be useful for anyone building more automated or repeatable 360° missions in Litchi for later panorama stitching from recorded video footage.

What it does

The advantage here is efficiency: portrait video gives you higher vertical coverage per frame, and continuous recording avoids stop-and-go capture delays. Combined with the even Fibonacci distribution, this results in a dataset that stitches cleanly into a high-resolution panorama or even a full 360° environment, depending on your pitch limits.

In short, you’re trading discrete photo capture for a smooth, continuous acquisition pass—while still preserving the geometric consistency needed for reliable stitching.

The script generates a ready-to-import .csv mission file for the Litchi Flight Hub using nothing more than a set of geo coordinates. It distributes waypoints over a partial sphere using a Fibonacci lattice and adds a micro-orbit pattern, which results in smooth and continuous capture— especially useful for 360° or structured scanning shots.

Key features

  • Automatic waypoint generation from a single lat/lon
  • Fibonacci-based spherical distribution for even coverage
  • Micro-orbit motion for allowing Litchi to recognize different waypoints
  • Configurable overlap between shots
  • Adjustable gimbal pitch limits (top to bottom coverage)
  • Optional portrait mode (9:16)
  • Built-in video start option at mission begin
  • Outputs directly to a Litchi-compatible CSV

The Fibunacci pattern in the 2D view as one picture may describe things better than thound words:

And a video of what the route would look like:

Raw video footage:

Usage examples

.\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050

With more options

.\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050 -Altitude 120 -PortraitMode -VideoMode

The created .csv file can be found in the folder of the powershell script.

The powershell script

Generate-LitchiMission.ps1
<#
.SYNOPSIS
    Generates a Litchi mission (Fibonacci spiral) as a CSV file for import into Litchi Flight Hub.

.DESCRIPTION
    Creates waypoints distributed over a partial sphere using a Fibonacci lattice.
    Applies a micro-orbit pattern to enable smooth, continuous video capture.

.PARAMETER Latitude
    Latitude of the capture location.

.PARAMETER Longitude
    Longitude of the capture location.

.PARAMETER PortraitMode
    Enables 9:16 (portrait) calculation.

.PARAMETER MinOverlap
    Desired overlap between shots (e.g., 0.30 = 30%).
    Default value is 0.30.

.PARAMETER MaxPitch
    Maximum upward gimbal tilt angle in degrees.
    Default value is 60.

.PARAMETER MinPitch
    Maximum downward gimbal tilt angle in degrees.
    Default value is -90.

.PARAMETER Radius
    Micro-orbit radius in meters.
    Default value is 50.

.PARAMETER Speed
    Drone speed factor (e.g., 0.30 = 0.3 meters/s).
    Default value is 0.30.

.PARAMETER VideoMode
Starts video recording at the first waypoint.

.PARAMETER Filename
    Output CSV file path.
    Default value is ".\litchi_360-degree-fibonacci-$Latitude_$Longitude.csv".

.EXAMPLE
    .\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050

.EXAMPLE
    .\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050 -Altitude 120 -PortraitMode -VideoMode

.NOTES
    Outputs a CSV file compatible with Litchi Flight Hub mission import.
#>

param(
    [Parameter(Mandatory=$true)][double]$Latitude,
    [Parameter(Mandatory=$true)][double]$Longitude,

    [double]$Altitude = 50,

    [switch]$PortraitMode,
    [double]$MinOverlap = 0.30,

    [double]$MinPitch = -90,
    [double]$MaxPitch = 60,

    [double]$Radius = 1.5,
    [double]$Speed = 0.3,

    [switch]$VideoMode,

    [string]$Filename = ".\litchi_360-degree-fibunacci-$Latitude-$Longitude-$Altitude.csv"
)

$culture = [System.Globalization.CultureInfo]::InvariantCulture

# --- 1. FOV & POINT CALCULATION ---
if ($PortraitMode) {
    $hFOV = 48.0; $vFOV = 75.0; $FormatName = "9:16 (Portrait)"
} else {
    $hFOV = 75.0; $vFOV = 48.0; $FormatName = "16:9 (Landscape)"
}

$hEff = ($hFOV * [Math]::PI / 180.0) * (1 - $MinOverlap)
$vEff = ($vFOV * [Math]::PI / 180.0) * (1 - $MinOverlap)
$omega_frame = $hEff * $vEff

$zMin = [Math]::Sin($MinPitch * [Math]::PI / 180.0)
$zMax = [Math]::Sin($MaxPitch * [Math]::PI / 180.0)
$zRange = $zMax - $zMin
$area_segment = 2 * [Math]::PI * $zRange
$requiredPoints = [Math]::Ceiling($area_segment / $omega_frame)

$PointsToGenerate = if ($requiredPoints -gt 99) { 99 } else { [Math]::Min(99, ($requiredPoints + 5)) }

Write-Host "Format: $FormatName | Radius: $Radius m" -ForegroundColor Cyan
Write-Host "Points: $PointsToGenerate (calculation for coverage)" -ForegroundColor Yellow

# --- 2. CSV HEADER ---
# Header needs to fit the Litchi format!
$header = "latitude,longitude,altitude(m),heading(deg),curvesize(m),rotationdir,gimbalmode,gimbalpitchangle," +
          "actiontype1,actionparam1,actiontype2,actionparam2,actiontype3,actionparam3,actiontype4,actionparam4," +
          "actiontype5,actionparam5,actiontype6,actionparam6,actiontype7,actionparam7,actiontype8,actionparam8," +
          "actiontype9,actionparam9,actiontype10,actionparam10,actiontype11,actionparam11,actiontype12,actionparam12," +
          "actiontype13,actionparam13,actiontype14,actionparam14,actiontype15,actionparam15," +
          "altitudemode,speed(m/s),poi_latitude,poi_longitude,poi_altitude(m),poi_altitudemode,photo_timeinterval,photo_distinterval"

$sb = New-Object System.Text.StringBuilder
[void]$sb.AppendLine($header)

# --- 3. GENERATION ---
$GoldenAngle = (2 * [Math]::PI) * (1 - 1/((1 + [Math]::Sqrt(5)) / 2))
$TotalTheoreticalPoints = [Math]::Round($PointsToGenerate * (2.0 / $zRange))

$EarthRadius = 6378137
$dLat_Per_M = 1 / ($EarthRadius * [Math]::PI / 180)

$count = 0

for ($i = 0; $i -lt $TotalTheoreticalPoints; $i++) {
    $z = -1 + (2 * $i / ($TotalTheoreticalPoints - 1))

    if ($z -ge $zMin -and $z -le $zMax) {
        if ($count -ge $PointsToGenerate) { break }

        # CAlculate angles
        $pitchDeg = ([Math]::Asin($z) * 180.0 / [Math]::PI)
        $theta = $i * $GoldenAngle
        $headingDeg = ($theta * 180.0 / [Math]::PI) % 360
        if ($headingDeg -lt 0) { $headingDeg += 360 }

        # Micro-orbit coordinates
        $dLat = [Math]::Cos($theta) * $Radius * $dLat_Per_M
        $latRad = $Latitude * [Math]::PI / 180
        $dLon = [Math]::Sin($theta) * $Radius * (1 / ($EarthRadius * [Math]::Cos($latRad) * [Math]::PI / 180))

        $sLat = ($Latitude + $dLat).ToString($culture)
        $sLon = ($Longitude + $dLon).ToString($culture)
        $sAlt = $Altitude.ToString($culture)
        $sHead = $headingDeg.ToString($culture)
        $sPitch = $pitchDeg.ToString($culture)
        $sCurve = ($Radius * 0.5).ToString($culture)
        $sSpeed = $Speed.ToString($culture)


        $act1_Type = "-1"; $act1_Param = "0"

        # Video Trigger at first point
        if ($VideoMode -and $count -eq 0) {
            $act1_Type = "2" # Start Recording
            $act1_Param = "0"
        }

        # Building strings
        $actionsString = "$act1_Type,$act1_Param"

        for ($k=0; $k -lt 14; $k++) {
            $actionsString += ",-1,0"
        }

        # AltitudeMode, hardcoded to 0 (relative to home / takeoff).
        $altMode = "0"

        # rotationdir=0, gimbalmode=2
        $line = "$sLat,$sLon,$sAlt,$sHead,$sCurve,0,2,$sPitch," +
                "$actionsString," +
                "$altMode,$sSpeed,0,0,0,0,-1,-1"

        [void]$sb.AppendLine($line)
        $count++
    }
}

try {
    $sb.ToString() | Out-File -FilePath $Filename -Encoding ASCII
    Write-Host "CSV successfully created: $Filename" -ForegroundColor Green
} catch { Write-Error $_ }

Testing

I have tested the created waypoint missions with my DJI Mini 3 Pro.

From what I understand one may good to use those settings:

  • Set a fitting White Balance for the conditions manually (for not having any color-shifts within parts of the pictures)
  • ISO 100
  • Allow the Shutter Speed do its’ thing in auto

This should produce the most crisp panorama images from my experiences. I was trying to set the SS manually and let lighting be adjusted by ISO being in auto - but results were having less contrast.

Stitching of panoramas

For stitching I am using some possibly not very well known Windows application, called “Image Compositing Editor”, the software allows to easily feed not only images, but videos for it working on a panorama. Additionally it allows for some further post corrections, also having a “auto-complete” function for filling gaps with some sort of algorithms (not known how exactly its done, think without any AI yet as it is an older piece of software already).

Example footage of stitched material

Raw & not further post edited panorama from the Image Composite Editor application:

Another example in Google Maps: Google Maps

Last comments

With the video footage of the waypoint missions I am getting very reliable results in ways of not having any huge gaps for any ground related objects - skies with fastly moving clouds or foggy conditions may create some artifacts.

If anyone is experimenting with automated capture workflows, 360 imagery, or just wants a faster way to build complex waypoint paths, feel free to try it out.

Example of a resulting route which has been imported as CSV: Litchi Hub

If anybody wants to take this proof-of-concept away to create even better solutions, please feel free - I would be happy for a backlink for me then knowing your better solution.

Best regards

3 Likes

Very cool,aFRI. I’ve looked at ICE’s “video pano” and wondered how to make it useful. I’ll be trying this…Thanks for your work!

1 Like

Such a nice post man! That was very clever! I want to try it!

1 Like

Worked great! I had to turn the video on and turn my Mini3 camera to Portrait before running the mission. and then in ICE (Image Compositing Editor) I cropped that “startup” camera extra video off ‘though I don’t know if it matters…anyways, it makes a nice Pano with good resolution just a tiny skyhole..oh, also works with Landscape too though the skyhole is going to be a little larger. (and there are several ways to fill a skyhole if it matters)

That was the thing I did forget, that in my poc I was working with manual start / stop. I left it there as I learned DJI may not allow SDKs available for all drones - so for the Mini 3 Pro, I need to adjust camera settings anyway manually & left it as is.

Glad it is working out for you as well @gorm !

This looks very promising. I’m anxious to try it myself. I’ll let you know how it turns out if/when I get a chance. Thanks for sharing with the community.

1 Like

…I’m still having fun with this script, aFri.

I managed to edit the Powershell script to raise the height to 75 metres (to get it higher above my tall conifers!), slowed speed down a wee bit (not sure if beneficial but thinking it’d give low lighting a better chance?), and I started interval photos instead of video…before running the mission. A two second interval made many more than needed( at the slower speed, by a factor of at least two!) but the stitching app I used handled them very well -especially the moving clouds which are so often problematic, and the resulting 360 panorama was, again, very good.

Really, starting the camera before the mission runs has been an advantage for me. The camera can be fine-set per exposure and White Balance etc..

1 Like

Happy to hear it is considered helpful somehow!

In theory the -Altitude Switch Should do the adjustments for height already. At least for my routes I could work with using just the parameter to have the altitude changed.

That makes sense. Keeping the altitude adjustment inside the script parameters seems cleaner than changing it manually later.

hmm. I run it in W10 and it doesn’t ask for anything except Lat and Long. I think I DO see the other queries in the script but they aren’t showing up. Perhaps I’m not running it properly? I’m not much of a windos person so I am letting windos run its default. But I guess now I should run it as

somewhere.

@gorm I think the default value has been 50 meters. But yes in theory you would just need to add the “-Altitude [value]” as another parameter to the script and this should already result in the right Altitude being set.

List of all possible Parameters / Switches which may be used

<#
.SYNOPSIS
Generates a Litchi mission (Fibonacci spiral) as a CSV file for import into Litchi Flight Hub.

.DESCRIPTION
Creates waypoints distributed over a partial sphere using a Fibonacci lattice.
Applies a micro-orbit pattern to enable smooth, continuous video capture.

.PARAMETER Latitude
Latitude of the capture location.

.PARAMETER Longitude
Longitude of the capture location.

.PARAMETER PortraitMode
Enables 9:16 (portrait) calculation.

.PARAMETER MinOverlap
Desired overlap between shots (e.g., 0.30 = 30%).
Default value is 0.30.

.PARAMETER MaxPitch
Maximum upward gimbal tilt angle in degrees.
Default value is 60.

.PARAMETER MinPitch
Maximum downward gimbal tilt angle in degrees.
Default value is -90.

.PARAMETER Radius
Micro-orbit radius in meters.
Default value is 50.

.PARAMETER Speed
Drone speed factor (e.g., 0.30 = 0.3 meters/s).
Default value is 0.30.

.PARAMETER VideoMode
Starts video recording at the first waypoint.

.PARAMETER Filename
Output CSV file path.
Default value is “.\litchi_360-degree-fibonacci-$Latitude_$Longitude.csv”.

.EXAMPLE
.\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050

.EXAMPLE
.\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050 -Altitude 120 -PortraitMode -VideoMode

.NOTES
Outputs a CSV file compatible with Litchi Flight Hub mission import.
#>

Any of those parameters can go as an additional one via a single dash, then the name. Hope this helps and does not confuse even more.. :smiley:

Edit: Ok, the Altitude has been forgotten to be documented in the synopsis I just realized.. But it can also be overwritten on the commandline..

Hi, aFri ! Yes I just happened to deduce it this morning after a fashion

param(
[Parameter(Mandatory=$true)][double]$Latitude,
[Parameter(Mandatory=$true)][double]$Longitude,
[Parameter(Mandatory=$true)][double]$Altitude,

works.

I’ll see what else I can do :slight_smile:

One thing I’m thinking is wanted is some kind of “echo” to say

South Latitudes and West Longitudes are negative values. Altitudes are meters

A mistake would show up on the Litchi Plannner but I can’t shake a vision of my drone taking off to Australia :slight_smile:

PS: W10 won’t let me run “.\Generate-LitchiMission.ps1 -Latitude etc etc” as a cmd line despite me running powershell as admin . and my brain is too soft to be faffing around with windos “policies” but I understand what you are saying.

1 Like

Would that look better for keeping your sanity for your drone not taking any route way southwards?! :smiley:

updated version in here
<#
.SYNOPSIS
    Generates a Litchi mission (Fibonacci spiral) as a CSV file for import into Litchi Flight Hub.

.DESCRIPTION
    Creates waypoints distributed over a partial sphere using a Fibonacci lattice.
    Applies a micro-orbit pattern to enable smooth, continuous video capture.

.PARAMETER Latitude
    Latitude of the capture location.

.PARAMETER Longitude
    Longitude of the capture location.

.PARAMETER Altitude
    Altitude of the capture location in meters.

.PARAMETER PortraitMode
    Enables 9:16 (portrait) calculation.

.PARAMETER MinOverlap
    Desired overlap between shots (e.g., 0.30 = 30%).
    Default value is 0.30.

.PARAMETER MaxPitch
    Maximum upward gimbal tilt angle in degrees.
    Default value is 60.

.PARAMETER MinPitch
    Maximum downward gimbal tilt angle in degrees.
    Default value is -90.

.PARAMETER Radius
    Micro-orbit radius in meters.
    Default value is 50.

.PARAMETER Speed
    Drone speed factor (e.g., 0.30 = 0.3 meters/s).
    Default value is 0.30.

.PARAMETER VideoMode
Starts video recording at the first waypoint.

.PARAMETER Filename
    Output CSV file path.
    Default value is ".\litchi_360-degree-fibonacci-$Latitude_$Longitude.csv".

.EXAMPLE
    .\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050

.EXAMPLE
    .\Generate-LitchiMission.ps1 -Latitude 52.5200 -Longitude 13.4050 -Altitude 120 -PortraitMode -VideoMode

.NOTES
    Outputs a CSV file compatible with Litchi Flight Hub mission import.
#>

param(
    [Parameter(Mandatory=$true)][double]$Latitude,
    [Parameter(Mandatory=$true)][double]$Longitude,

    [double]$Altitude = 50,

    [switch]$PortraitMode,
    [double]$MinOverlap = 0.30,

    [double]$MinPitch = -90,
    [double]$MaxPitch = 60,

    [double]$Radius = 1.5,
    [double]$Speed = 0.3,

    [switch]$VideoMode,

    [string]$Filename = ".\litchi_360-degree-fibunacci-($Latitude)-($Longitude)-($Altitude).csv"
)

# Determine north/south
if ($Latitude -gt 0) {
    $LatHemisphere = "Northern Hemisphere"
}
elseif ($Latitude -lt 0) {
    $LatHemisphere = "Southern Hemisphere"
}
else {
    $LatHemisphere = "Equator"
}

# Determine east/west
if ($Longitude -gt 0) {
    $LonHemisphere = "Eastern Hemisphere"
}
elseif ($Longitude -lt 0) {
    $LonHemisphere = "Western Hemisphere"
}
else {
    $LonHemisphere = "Prime Meridian"
}

$culture = [System.Globalization.CultureInfo]::InvariantCulture

# --- 1. FOV & POINT CALCULATION ---
if ($PortraitMode) {
    $hFOV = 48.0; $vFOV = 75.0; $FormatName = "9:16 (Portrait)"
} else {
    $hFOV = 75.0; $vFOV = 48.0; $FormatName = "16:9 (Landscape)"
}

$hEff = ($hFOV * [Math]::PI / 180.0) * (1 - $MinOverlap)
$vEff = ($vFOV * [Math]::PI / 180.0) * (1 - $MinOverlap)
$omega_frame = $hEff * $vEff

$zMin = [Math]::Sin($MinPitch * [Math]::PI / 180.0)
$zMax = [Math]::Sin($MaxPitch * [Math]::PI / 180.0)
$zRange = $zMax - $zMin
$area_segment = 2 * [Math]::PI * $zRange
$requiredPoints = [Math]::Ceiling($area_segment / $omega_frame)

$PointsToGenerate = if ($requiredPoints -gt 99) { 99 } else { [Math]::Min(99, ($requiredPoints + 5)) }

# Friendly reminder
Write-Host "`nReminder:"
Write-Host "`t- South latitudes and west longitudes must use negative values." -ForegroundColor Cyan
Write-Host "`t- Altitude values are interpreted as meters." -ForegroundColor Cyan
Write-Host "`t- Please always check the route at https://hub.flylitchi.com/ first before using it!`n" -ForegroundColor Cyan

# Output info
Write-Host "Mission summary:"
Write-Host "`tLatitude:`t`t$Latitude ($LatHemisphere)"  -ForegroundColor Yellow
Write-Host "`tLongitude:`t`t$Longitude ($LonHemisphere)"  -ForegroundColor Yellow
Write-Host "`tAltitude:`t`t$Altitude (meters)"  -ForegroundColor Yellow
Write-Host "`tDrone Speed:`t`t$Speed (meter/second)"  -ForegroundColor Yellow
Write-Host "`tRoute Radius:`t`t$Radius (meters)`n" -ForegroundColor Yellow

Write-Host "`tCamera minimum Pitch:`t$MinPitch (degree)"  -ForegroundColor Yellow
Write-Host "`tCamera maximum Pitch:`t$MaxPitch (degree)"  -ForegroundColor Yellow
Write-Host "`tFormat:`t`t`t$FormatName" -ForegroundColor Yellow
Write-Host "`tImage overlap:`t`t$($MinOverlap*100)%"  -ForegroundColor Yellow

# --- 2. CSV HEADER ---
# Header needs to fit the Litchi format!
$header = "latitude,longitude,altitude(m),heading(deg),curvesize(m),rotationdir,gimbalmode,gimbalpitchangle," +
          "actiontype1,actionparam1,actiontype2,actionparam2,actiontype3,actionparam3,actiontype4,actionparam4," +
          "actiontype5,actionparam5,actiontype6,actionparam6,actiontype7,actionparam7,actiontype8,actionparam8," +
          "actiontype9,actionparam9,actiontype10,actionparam10,actiontype11,actionparam11,actiontype12,actionparam12," +
          "actiontype13,actionparam13,actiontype14,actionparam14,actiontype15,actionparam15," +
          "altitudemode,speed(m/s),poi_latitude,poi_longitude,poi_altitude(m),poi_altitudemode,photo_timeinterval,photo_distinterval"

$sb = New-Object System.Text.StringBuilder
[void]$sb.AppendLine($header)

# --- 3. GENERATION ---
$GoldenAngle = (2 * [Math]::PI) * (1 - 1/((1 + [Math]::Sqrt(5)) / 2))
$TotalTheoreticalPoints = [Math]::Round($PointsToGenerate * (2.0 / $zRange))

$EarthRadius = 6378137
$dLat_Per_M = 1 / ($EarthRadius * [Math]::PI / 180)

$count = 0

for ($i = 0; $i -lt $TotalTheoreticalPoints; $i++) {
    $z = -1 + (2 * $i / ($TotalTheoreticalPoints - 1))

    if ($z -ge $zMin -and $z -le $zMax) {
        if ($count -ge $PointsToGenerate) { break }

        # CAlculate angles
        $pitchDeg = ([Math]::Asin($z) * 180.0 / [Math]::PI)
        $theta = $i * $GoldenAngle
        $headingDeg = ($theta * 180.0 / [Math]::PI) % 360
        if ($headingDeg -lt 0) { $headingDeg += 360 }

        # Micro-orbit coordinates
        $dLat = [Math]::Cos($theta) * $Radius * $dLat_Per_M
        $latRad = $Latitude * [Math]::PI / 180
        $dLon = [Math]::Sin($theta) * $Radius * (1 / ($EarthRadius * [Math]::Cos($latRad) * [Math]::PI / 180))

        $sLat = ($Latitude + $dLat).ToString($culture)
        $sLon = ($Longitude + $dLon).ToString($culture)
        $sAlt = $Altitude.ToString($culture)
        $sHead = $headingDeg.ToString($culture)
        $sPitch = $pitchDeg.ToString($culture)
        $sCurve = ($Radius * 0.5).ToString($culture)
        $sSpeed = $Speed.ToString($culture)


        $act1_Type = "-1"; $act1_Param = "0"

        # Video Trigger at first point
        if ($VideoMode -and $count -eq 0) {
            $act1_Type = "2" # Start Recording
            $act1_Param = "0"
        }

        # Building strings
        $actionsString = "$act1_Type,$act1_Param"

        for ($k=0; $k -lt 14; $k++) {
            $actionsString += ",-1,0"
        }

        # AltitudeMode, hardcoded to 0 (relative to home / takeoff).
        $altMode = "0"

        # rotationdir=0, gimbalmode=2
        $line = "$sLat,$sLon,$sAlt,$sHead,$sCurve,0,2,$sPitch," +
                "$actionsString," +
                "$altMode,$sSpeed,0,0,0,0,-1,-1"

        [void]$sb.AppendLine($line)
        $count++
    }
}

try {
    $sb.ToString() | Out-File -FilePath $Filename -Encoding ASCII
    Write-Host "`nCSV successfully created: $Filename" -ForegroundColor Green
} catch { Write-Error $_ }

Besides the added reminder and the little logic for also printing the hemispheres, I changed the output format of the file to better reflect negative values with adding parantheses around them.

1 Like

For you not being able to start the script, I asked AI to create me a guide for the Execution Policies from Microsoft.

Description from AI about Execution Policies

The PowerShell Execution Policy is a safety guardrail that decides whether you are allowed to run automation scripts on your computer. Think of it like a safety switch on a power tool: it does not stop professional hackers (who can easily bypass it), but it stops everyday users from accidentally running a dangerous script they downloaded from the internet.

:hammer_and_wrench: The Common Policy Modes

When you use the command Set-ExecutionPolicy, you have to pick a mode. Here they are from strictest to most open:

  • Restricted
    • The default Windows setting.
    • Blocks all script execution completely.
    • You can only type single commands by hand.
  • AllSigned
    • Scripts can run, but only if they are digitally signed by a trusted developer.
    • If you write your own script, it will not run unless you sign it.
  • RemoteSigned :backhand_index_pointing_left: (Recommended for Beginners)
    • Scripts you wrote on your own computer run instantly with no issues.
    • Scripts downloaded from the internet must be digitally signed.
  • Unrestricted
    • Any script can run.
    • Windows will still show a warning pop-up for files downloaded from the web.
  • Bypass
    • Everything runs with zero warnings or blocks.
    • Usually used by automated software installation tools.

:laptop: How to Change It

If you downloaded a script or wrote a .ps1 file and saw a red error saying “script execution is disabled,” you need to change this setting.

  1. Click Start, search for PowerShell.
  2. Right-click it and choose Run as Administrator.
  3. To allow your own scripts to run safely, type this exact command and press Enter:

powershell

Set-ExecutionPolicy RemoteSigned
  1. Press Y (Yes) or A (Yes to All) when it asks for your permission.

:magnifying_glass_tilted_left: Helpful Troubleshooting Tips

  • Check your current setting: Type Get-ExecutionPolicy to see what mode your computer is currently using.
  • Temporary Bypassing: If you do not want to change your computer’s permanent settings, you can open a single, temporary session that allows scripts by launching Windows Command Prompt (CMD) and typing: powershell -ExecutionPolicy Bypass.

Official documentation from Microsoft: Set-ExecutionPolicy (Microsoft.PowerShell.Security) - PowerShell | Microsoft Learn

My script is not signed. I would not recommend a regular user to use the option “Unrestricted” - instead better go with the last paragraph of starting a singular powershell window with the “bypass”.

1 Like

Thanks, aFri- that’s a Big Help! Much better now.

1 Like