近期换了Win11,发现现在Win下的powershell也可以像macOS的zsh那样,配合iterm2做一番美化,网上搜了很多文章,但是大部分都比较老旧,已经不符合现在版本的安装方式,所以跟着官方文档一步一步走,发现步骤非常简单,并不如网上说的那么复杂,便有此一记。

1. 环境说明

  • Windows11专业版  22H2
  • 安装vscode,并且配置了环境变量,可以使用code来打开vscode

2. 安装oh-my-posh

1
winget install JanDeDobbeleer.OhMyPosh -s winget

winget在Windows11中默认就有了,也挺好用,没不要在单独安装sqoop(和macOS上的brew类似)之类的工具。

请不要使用网上各种文章的Install-Module oh-my-posh -Scope CurrentUser,官方已经不推荐了。 
参考文档:PowerShell module Oh My Posh

3. 配置oh-my-posh

1
code $Profile

填入如下内容:

1
oh-my-posh init pwsh  Invoke-Expression

重启PowerShell。

此时会打开一个默认主题的Shell,并且有大量的乱码。

4. 下载字体

配置过oh-my-zsh的都知道,此时需要一些名为powerline的字体文件才可以正确显示,我试过使用sqoop下载字体,或者手动下载字体包去安装,经常会遇到打开power shell的时候,提示字体文件未找到的问题。但是通过如下方式下载并安装字体就再也不会出现这个问题。

1
oh-my-posh font install

选择JetBrainsMono,等待下载即可。喜欢其他的请自行选择,可点击查看预览Nerd Fonts - Iconic font aggregator, glyphs/icons collection, & fonts patcher

下载完成后这些乱码就消失了。

5. 安装插件

插件可以使oh-my-posh和power shell更为强大,这里只需要安装如下几个插件即可。

1
2
3
4
5
6
7
8
# Git插件
Install-Module posh-git -Scope CurrentUser
# 自动补全
Install-Module -Name PSReadLine -Scope CurrentUser -Force
# 给目录加图标
Install-Module -Name Terminal-Icons -Repository PSGallery
# 给目录加颜色
Install-Module DirColors

然后编辑$Profile

1
code $Profile

添加如下信息:

1
2
3
4
Import-Module DirColors
Import-Module -Name Terminal-Icons
Import-Module posh-git
Import-Module PSReadLine

然后重启PowerShell。

6. 更换主题

觉得默认主题不好看?那就换一个,执行如下命令,可预览主题

1
Get-PoshThemes

看到中意的主题,继续修改配置文件,只需替换`主题名.omp.json`就行,实际情况根据你得路径来设置。

最终配置如下:

1
2
3
4
5
6
7
8
code $Profile

# oh-my-posh init pwsh Invoke-Expression
oh-my-posh init pwsh --config 'C:\Program Files (x86)\oh-my-posh\themes\unicorn.omp.json' Invoke-Expression
Import-Module DirColors
Import-Module -Name Terminal-Icons
Import-Module posh-git
Import-Module PSReadLine

unicorn就是我们选中的主题名。

7. 效果图

优点是界面更好看了,缺点嘛,第一次打开power shell会很慢,如图中所示,加载配置使用了3356毫秒。

8. 配置代理

对于有代理需求的,可以在PowerShell中新增配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 配置代理
function set_proxy_variable {
$proxy = 'http://127.0.0.1:1080'

# temporary
$env:HTTP_PROXY = $proxy
$env:HTTPS_PROXY = $proxy

# forever
# [System.Environment]::SetEnvironmentVariable("HTTP_PROXY", $proxy, "User")
# [System.Environment]::SetEnvironmentVariable("HTTPS_PROXY", $proxy, "User")

Write-Host "`n OPEN powershell proxy channel!`n"
}

function unset_proxy_variable {
# temporary
Remove-Item env:HTTP_PROXY
Remove-Item env:HTTPS_PROXY

# forever
# [Environment]::SetEnvironmentVariable('http_proxy', $null, 'User')
# [Environment]::SetEnvironmentVariable('https_proxy', $null, 'User')

Write-Host "`n CLOSE powershell proxy channel!`n"
}

Set-Alias proxy set_proxy_variable
Set-Alias unproxy unset_proxy_variable

配置完成后,重新打开PowerShell,输入proxy即可开启代理,输入unproxy即可关闭代理。

推荐大家升级到PowerShell 7 。

1
winget install --id Microsoft.Powershell --source winget

2026年3月16日更新,下面贴一下我最新的配置,做了一点优化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# 禁用 oh-my-posh 自动更新检查
$env:POSH_CHECK_UPDATE = "off"
# 设置终端编码为 UTF-8
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
# 配置 oh-my-posh 主题
$ompConfig = "$env:POSH_THEMES_PATH\jandedobbeleer.omp.json"
# 如果自定义配置文件不存在,则使用 powerline 主题
if (!(Test-Path $ompConfig)) { $ompConfig = "$env:POSH_THEMES_PATH\powerline.omp.json" }
# 显式指定配置路径避免搜索,并开启缓存
oh-my-posh init pwsh --config $ompConfig Invoke-Expression
# oh-my-posh init pwsh --config 'C:\Program Files (x86)\oh-my-posh\themes\powerline.omp.json' Invoke-Expression
# 核心模块 优先加载
Import-Module PSReadLine

# 延迟加载
$slowModules = @("DirColors", "Terminal-Icons", "posh-git", "Microsoft.WinGet.CommandNotFound")
foreach ($mod in $slowModules) {
if (Get-Module -ListAvailable -Name $mod) {
Import-Module $mod -ErrorAction SilentlyContinue
}
}

# Import-Module DirColors
# Import-Module -Name Terminal-Icons
# Import-Module posh-git
# uv 自动补全
if (Get-Command uv -ErrorAction SilentlyContinue) {
(& uv generate-shell-completion powershell) Out-String Invoke-Expression
}

# 导入 Scoop 补全模块
if (Get-Module -ListAvailable -Name scoop-completion) {
Import-Module scoop-completion
}

# 使用 scoop-search 完美接管原生 scoop search 命令
if (Get-Command scoop-search -ErrorAction SilentlyContinue) {
. ([ScriptBlock]::Create((& scoop-search --hook Out-String)))
}

# 设置预测文本来源为历史记录
Set-PSReadLineOption -PredictionSource History
# 预测列表
Set-PSReadLineOption -PredictionViewStyle ListView

# 每次回溯输入历史,光标定位于输入内容末尾
Set-PSReadLineOption -HistorySearchCursorMovesToEnd

# 设置 Tab 为菜单补全和 Intellisense
Set-PSReadLineKeyHandler -Key "Tab" -Function MenuComplete

# 设置向上键为后向搜索历史记录
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward

# 设置向下键为前向搜索历史纪录
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward

# 查看目录 ls & ll
function ListDirectory {
(Get-ChildItem).Name
Write-Host("")
}
Set-Alias -Name ll -Value Get-ChildItem

# 配置代理
function set_proxy_variable {
$proxy = 'http://127.0.0.1:1080'

# temporary
$env:HTTP_PROXY = $proxy
$env:HTTPS_PROXY = $proxy

# forever
# [System.Environment]::SetEnvironmentVariable("HTTP_PROXY", $proxy, "User")
# [System.Environment]::SetEnvironmentVariable("HTTPS_PROXY", $proxy, "User")

Write-Host "`n OPEN powershell proxy channel!`n"
}

function unset_proxy_variable {
# temporary
Remove-Item env:HTTP_PROXY
Remove-Item env:HTTPS_PROXY

# forever
# [Environment]::SetEnvironmentVariable('http_proxy', $null, 'User')
# [Environment]::SetEnvironmentVariable('https_proxy', $null, 'User')

Write-Host "`n CLOSE powershell proxy channel!`n"
}

Set-Alias proxy set_proxy_variable
Set-Alias unproxy unset_proxy_variable
#f45873b3-b655-43a6-b217-97c00aa0db58 PowerToys CommandNotFound module

# Import-Module -Name Microsoft.WinGet.CommandNotFound
#f45873b3-b655-43a6-b217-97c00aa0db58
# $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding

# 计算指定目录下各子目录大小的函数,默认以 MB 为单位显示,使用 -GB 参数可改为 GB
function Get-DirSize {
param (
[string]$Path = ".",
[switch]$GB
)

Write-Host "正在计算目录大小,请稍候..." -ForegroundColor Cyan

Get-ChildItem -Path $Path -Directory ForEach-Object {
$subFiles = Get-ChildItem $_.FullName -Recurse -File -ErrorAction SilentlyContinue
$sizeSum = ($subFiles Measure-Object -Property Length -Sum).Sum

# 默认显示 MB,如果指定 -GB 参数则显示 GB
if ($GB) {
$finalSize = [math]::Round($sizeSum / 1GB, 2)
$unit = "GB"
} else {
$finalSize = [math]::Round($sizeSum / 1MB, 2)
$unit = "MB"
}

[PSCustomObject]@{
FolderName = $_.Name
Size = "$finalSize $unit"
RawSize = $sizeSum # 用于后续排序
}
} Sort-Object RawSize -Descending Select-Object FolderName, Size
}

# 开发PHP 启动NGINX和PHP (没安装可以不加)
function start-wnmp {
echo "Starting PHP FastCGI..."
Start-Process "php-cgi" -ArgumentList "-b 127.0.0.1:9000" -WindowStyle Hidden
echo "Starting Nginx..."
Start-Process "nginx" -WorkingDirectory (scoop prefix nginx) -WindowStyle Hidden
echo "WNMP is running!"
}

function stop-wnmp {
taskkill /f /im nginx.exe
taskkill /f /im php-cgi.exe
echo "WNMP stopped."
}