PowerShell has no idea what Hugo's flags are until you feed it Hugo's own completion script, one pipeline at a time. You will generate that script, load it into the current session, and optionally make it available whenever PowerShell starts. The examples use Hugo 0.123.7 from the installed Ubuntu package. Allow about ten minutes if Hugo and PowerShell are already installed.
This command only generates shell code. It does not edit a Hugo site, change a Hugo configuration file, or need administrator privileges. The persistent setup changes your PowerShell profile, so the guide makes a backup first and shows how to undo that change.
Run the version command from the shell where Hugo is installed:
$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2026-03-17T19:51:14Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3+esm2
Your build date or vendor suffix can differ. The completion subcommand is part of the Hugo command-line program, so a missing command is an installation or PATH problem rather than a PowerShell completion problem.
Checkpoint: continue only when hugo version succeeds. If it does not, fix the Hugo installation in your normal package-management workflow before changing a PowerShell profile.
Ask Hugo for the PowerShell script and inspect the first lines without loading it:
$ hugo completion powershell | Select-Object -First 12
# powershell completion for hugo -*- shell-script -*-
function __hugo_debug {
if ($env:BASH_COMP_DEBUG_FILE) {
"$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE"
}
}
The installed command writes the generated script to standard output; it does not write a completion file for you. On this machine the complete output is 245 lines, though generated output can change between Hugo releases. The first line should identify PowerShell completion for Hugo.
Descriptions are enabled by default. If you prefer shorter suggestions, generate the alternative form with:
hugo completion powershell --no-descriptions | Select-Object -First 2
--no-descriptions changes the generated suggestions; it does not disable completion itself. Pick one form and use that same form for the temporary and persistent setup.
In PowerShell, pipe the script through Out-String and then evaluate it:
hugo completion powershell | Out-String | Invoke-Expression
This affects only the current PowerShell process. It does not add anything to your profile and normally prints no output. Start typing a Hugo command and press Tab to check the result:
hugo --<Tab>
PowerShell may cycle through several matching options rather than displaying a fixed list, depending on its completion view. Try a more specific prefix such as hugo --en<Tab>; you should get a Hugo option such as --environment. If Tab does nothing, confirm you ran the loading command in PowerShell, not in Bash, and that the command itself completed without an error.
Checkpoint: close this PowerShell window and open another one. The completion should disappear because this step was deliberately temporary.
For completion in future sessions, add the loading command to the profile that PowerShell reports as $PROFILE. First inspect its location and preserve an existing file:
$PROFILE
if (Test-Path -LiteralPath $PROFILE) {
Copy-Item -LiteralPath $PROFILE -Destination "$PROFILE.before-hugo-completion" -Force
}
The backup is placed beside the profile and is overwritten if you repeat this exact command. If you already have a backup you want to keep, copy the profile to a different filename before proceeding. No elevated shell is needed unless you deliberately keep the profile in a directory your account cannot write.
Create the profile directory if necessary, then append the documented loading command:
$profileDirectory = Split-Path -Parent $PROFILE
if (-not (Test-Path -LiteralPath $profileDirectory)) {
New-Item -ItemType Directory -Path $profileDirectory -Force | Out-Null
}
Add-Content -LiteralPath $PROFILE -Value 'hugo completion powershell | Out-String | Invoke-Expression'
This changes only the profile named by $PROFILE. It does not reload the current session automatically. Open a new PowerShell window, or run the profile explicitly in the current one:
. $PROFILE
hugo --<Tab>
Warning: do not run the append block repeatedly without checking the file. Each run adds another identical line. Repeated definitions are usually harmless, but they make troubleshooting and later removal harder.
If your profile should not depend on completion descriptions, replace the line with the --no-descriptions form:
hugo completion powershell --no-descriptions | Out-String | Invoke-Expression
Use one variant, not both. If Hugo is not available on the PATH when PowerShell starts, the profile will report an error during startup. In that case, fix the PATH or guard the line until Hugo is installed:
if (Get-Command hugo -ErrorAction SilentlyContinue) {
hugo completion powershell | Out-String | Invoke-Expression
}
This guard is useful on machines where the same profile is shared across systems with different software. It can also hide an accidental broken installation, so check Get-Command hugo when completion unexpectedly vanishes.
Profile edits are ordinary text changes. Open the profile and remove only the Hugo completion line:
notepad $PROFILE
Recovery: save the file, start a new PowerShell session, and test that the Hugo suggestions are no longer loaded. If the profile contained no other changes after the backup, you can restore it with:
Copy-Item -LiteralPath "$PROFILE.before-hugo-completion" -Destination $PROFILE -Force
Check the backup filename before using that command. Restoring it replaces the current profile, so copy the current file to another safe name first if it contains unrelated work.
Get-Command hugo and hugo version. Do not add a guessed path to the profile.Out-String and Invoke-Expression.hugo version identifies the installed Hugo build.hugo completion powershell produces a non-empty PowerShell script.Out-String and Invoke-Expression.--environment.