PowerShell で作った neofetch風 function の話
唐突ですが、neofetch って良いですよね。
あのLinuxで環境構築後に表示したくなるアレですが、 PowerShell 学習のために簡易的なものを真似して作ってみました。
1. システム環境を表示させるコマンドを探す
ではまず、function を作成する前にまずはコマンドを調査。
表示させる内容は何でも良いので、なんとなく思いついたものを並べてみます。
CPU、OS、Motherboard、Model、Memory容量、Disk容量、GPU、Locale、Shell、カラーパレット...
システム環境を表示させる方法を調査していたところ、Get-WmiObject で色々引き出せる様なので早速入力してみます。
Get-WmiObject
コマンド パイプライン位置 1 のコマンドレット Get-WmiObject
次のパラメーターに値を指定してください:
Class:
うん、という事でWEBで詳細を調べました。
・CPU Get-WmiObject -Class Win32_Processor
・OS Get-WmiObject -Class Win32_OperatingSystem
・Motherboard Get-WmiObject Win32_BaseBoard
・Model Get-WmiObject Win32_ComputerSystemProduct
・Memory Get-WmiObject Win32_PhysicalMemory
・Disk Get-WmiObject Win32_DiskDrive
表示させたい情報の内上記の6項目はこれで表示出来そうですね。
それでは、CPU の情報を表示させるコマンドを入力してみましょう。
Get-WmiObject -Class Win32_Processor
# 結果
Caption : AMD64 Family 25 Model 80 Stepping 0
DeviceID : CPU0
Manufacturer : AuthenticAMD
MaxClockSpeed : 3901
Name : AMD Ryzen 5 5600G with Radeon Graphics
SocketDesignation : AM4
この要素で構成されているようです。
これを要素ごとに個別に取り出すには変数に代入して要素の名前を指定します。
$wmi1 = Get-WmiObject -Class Win32_Processor
$cpu = $wmi1.Name
$cpu
# 結果
AMD Ryzen 5 5600G with Radeon Graphics
CPU情報を変数に代入出来ました。
この要領で全ての項目を変数に代入していきます。
# OS 情報
$wmi2 = Get-WmiObject -Class Win32_OperatingSystem
$os = $wmi2.Caption + " " + $wmi2.Version
$os
# 結果
Microsoft Windows 11 Home 10.0.26100
------------------------------------------------------------
# Motherboard 情報
$wmi3 = Get-WmiObject Win32_BaseBoard
$motherboard = $wmi3.Product + " " + $wmi1.SocketDesignation
#ソケット情報も表示したいので $wmi1.SocketDesignation を追加しました。
$motherboard
# 結果
MAG B550M MORTAR WIFI (MS-7C94)
------------------------------------------------------------
# Model 情報
$wmi4 = Get-WmiObject Win32_ComputerSystemProduct
$model = $wmi4.Vendor + $wmi4.Name
$model
# 結果
Micro-Star International Co., Ltd.MS-7C94
------------------------------------------------------------
# Memory と Disk は複数取り付けてあるので、容量のみを " / " で繋げて表示します。
# Memory 情報
$wmi5 = Get-WmiObject Win32_PhysicalMemory
$m_capa = $wmi5.Capacity
$memory = ""
$flag = $false
foreach($buf in $m_capa){
if($flag){
$memory += " / "
}else{
$flag = $true
}
$m_size = [long]$buf
$m_size = [math]::Round($m_size / 1000000000, 2)
$memory += [string]$m_size + "Gb"
}
# 結果
17.18Gb / 17.18Gb
------------------------------------------------------------
# Disk 情報
$wmi6 = Get-WmiObject Win32_DiskDrive
$disk = ""
$flag = $false
foreach($buf in $wmi6){
if($flag){
$disk += " / "
}else{
$flag = $true
}
$d_size = [long]$buf.Size
if($d_size -ge 1000000000000){
$d_size = [math]::Round($d_size / 1000000000000, 2)
$disk += [string]$d_size + "Tb"
}else{
$d_size = [math]::Round($d_size / 1000000000, 2)
$disk += [string]$d_size + "Gb"
}
}
# 結果
512.11Gb / 1Tb / 1Tb
Get-WmiObject で取得できない以下の項目は別のコマンドで代入ですね。
・GPU Get-CimInstance CIM_VideoController
・Locale Get-WinSystemLocale
・Shell $PSversiontable.PSVersion
では、代入してみます。
# GPU 情報
$gpu = Get-CimInstance CIM_VideoController
$gpu_name = $gpu.Name
$gpu_name
# 結果(CPU内臓のものと2つ表示されています)
AMD Radeon(TM) Graphics
NVIDIA GeForce GTX 1650
------------------------------------------------------------
# Locale
$locale = Get-WinSystemLocale
$locale_name = $locale.Name + " " + $locale.DisplayName
$locale_name
#結果
ja-JP 日本語 (日本)
------------------------------------------------------------
# ShellのVersion
$shell = "PowerShell " + $PSversiontable.PSVersion
#PowerShell って表示されなかったので足しました。
$shell
#結果
PowerShell 7.5.1
最後にカラーパレットですが、これは空白にバックグラウンドカラーを付ける事で表示させようと思います。
Write-Host " " -BackgroundColor "DarkGray" -NoNewline; Write-Host " " -BackgroundColor "Red" -NoNewline; Write-Host " " -BackgroundColor "Green" -NoNewline; Write-Host " " -BackgroundColor "Yellow" -NoNewline; Write-Host " " -BackgroundColor "Blue" -NoNewline; Write-Host " " -BackgroundColor "Magenta" -NoNewline; Write-Host " " -BackgroundColor "Cyan" -NoNewline; Write-Host " " -BackgroundColor "White" -NoNewline; Write-Host ""
ここまでで、今回表示させたいComputerの情報を string に代入する方法が確認出来ました。
2. function を作成
次に、一旦 Computer 情報を並べて表示する function を作成してみます。
PowerShell のプロファイルを開く。
code $profile
function を次のように作成します。function名は netch です。
function netch(){
# CPU
$wmi1 = Get-WmiObject -Class Win32_Processor
$cpu = $wmi1.Name
# OS
$wmi2 = Get-WmiObject -Class Win32_OperatingSystem
$os = $wmi2.Caption + " " + $wmi2.Version
# Motherboard
$wmi3 = Get-WmiObject Win32_BaseBoard
$motherboard = $wmi3.Product + " " + $wmi1.SocketDesignation
# Model
$wmi4 = Get-WmiObject Win32_ComputerSystemProduct
$model = $wmi4.Vendor + $wmi4.Name
# Memory
$wmi5 = Get-WmiObject Win32_PhysicalMemory
$m_capa = $wmi5.Capacity
$memory = ""
$flag = $false
foreach($buf in $m_capa){
if($flag){
$memory += " / "
}else{
$flag = $true
}
$m_size = [long]$buf
$m_size = [math]::Round($m_size / 1000000000, 2)
$memory += [string]$m_size + "Gb"
}
# Disk
$wmi6 = Get-WmiObject Win32_DiskDrive
$disk = ""
$flag = $false
foreach($buf in $wmi6){
if($flag){
$disk += " / "
}else{
$flag = $true
}
$d_size = [long]$buf.Size
if($d_size -ge 1000000000000){
$d_size = [math]::Round($d_size / 1000000000000, 2)
$disk += [string]$d_size + "Tb"
}else{
$d_size = [math]::Round($d_size / 1000000000, 2)
$disk += [string]$d_size + "Gb"
}
}
# GPU
$gpu = Get-CimInstance CIM_VideoController
$gpu_name = $gpu.Name
# Locale
$locale = Get-WinSystemLocale
$locale_name = $locale.Name + " " + $locale.DisplayName
# Shell
$shell = "PowerShell " + $PSversiontable.PSVersion
# 空行
Write-Host ""
# UserNameを表示
Write-Host $env:USERNAME -ForegroundColor "Green"
# 区切り線
Write-Host "------------------------------------------------------------" -ForegroundColor "White"
# 情報を順番に表示
Write-Host "CPU: " -ForegroundColor "Cyan" -NoNewline; Write-Host $cpu -ForegroundColor "White"
Write-Host "OS: " -ForegroundColor "Cyan" -NoNewline; Write-Host $os -ForegroundColor "White"
Write-Host "Motherboard: " -ForegroundColor "Cyan" -NoNewline; Write-Host $motherboard -ForegroundColor "White"
Write-Host "Model: " -ForegroundColor "Cyan" -NoNewline; Write-Host $model -ForegroundColor "White"
Write-Host "Memory: " -ForegroundColor "Cyan" -NoNewline; Write-Host $memory -ForegroundColor "White"
Write-Host "Disk: " -ForegroundColor "Cyan" -NoNewline; Write-Host $disk -ForegroundColor "White"
Write-Host "Graphics: " -ForegroundColor "Cyan" -NoNewline; Write-Host $gpu_name -ForegroundColor "White"
Write-Host "Locale: " -ForegroundColor "Cyan" -NoNewline; Write-Host $locale_name -ForegroundColor "White"
Write-Host "Shell: " -ForegroundColor "Cyan" -NoNewline; Write-Host $shell -ForegroundColor "White"
# 空行
Write-Host ""
# カラーパレットを表示
Write-Host " " -BackgroundColor "Black" -NoNewline; Write-Host " " -BackgroundColor "DarkRed" -NoNewline; Write-Host " " -BackgroundColor "DarkGreen" -NoNewline; Write-Host " " -BackgroundColor "DarkYellow" -NoNewline; Write-Host " " -BackgroundColor "DarkBlue" -NoNewline; Write-Host " " -BackgroundColor "DarkMagenta" -NoNewline; Write-Host " " -BackgroundColor "DarkCyan" -NoNewline; Write-Host " " -BackgroundColor "Gray" -NoNewline; Write-Host ""
Write-Host " " -BackgroundColor "DarkGray" -NoNewline; Write-Host " " -BackgroundColor "Red" -NoNewline; Write-Host " " -BackgroundColor "Green" -NoNewline; Write-Host " " -BackgroundColor "Yellow" -NoNewline; Write-Host " " -BackgroundColor "Blue" -NoNewline; Write-Host " " -BackgroundColor "Magenta" -NoNewline; Write-Host " " -BackgroundColor "Cyan" -NoNewline; Write-Host " " -BackgroundColor "White" -NoNewline; Write-Host ""
# 空行
Write-Host ""
# 変数を消す
$wmi1 = $wmi2 = $wmi3 = $wmi4 = $wmi5 = $wmi6 = $cpu = $os = $motherboard = $model = $memory = $disk = $gpu = $locale = $shell = $m_capa = $m_size = $flag = $d_size = $buf = $gpu_name = $locale_name = $null
[GC]::Collect()
}
Microsoft.PowerShell_profile.ps1 を保存してShellで再読み込みします。
. $profile
では、ファンクションを実行してみます。
netch
意図した通りに表示されました。
3. それっぽいロゴを表示させる
最終仕上げ。左側にそれっぽいロゴを入れて完成させます。もちろん、ここが一番時間掛かりました。(学習か苦行か)
# 今回作ってみたコレを青と白の2色で入れます(素人なので温かい目で)
:--:--:--:--:--:--:--:--:--:--:--:--:--:
+..+posh.+..+..+..+..+..+..+..+..+..+..+
:--:--posh--:--:--:--:--:--:--:--:--:--:
+..+..+.posh+..+..+..+..+..+..+..+..+..+
:--:--:--:posh-:--:--:--:--:--:--:--:--:
+..+..+..+..posh..+..+..+..+..+..+..+..+
:--:--:--:--:-posh:--:--:--:--:--:--:--:
+..+..+..+..+..+posh.+..+..+..+..+..+..+
:--:--:--:--:--:--posh--:--:--:--:--:--:
+..+..+..+..+..+posh.+..+..+..+..+..+..+
:--:--:--:--:-posh:--:--:--:--:--:--:--:
+..+..+..+..posh..+..+..+..+..+..+..+..+
:--:--:--:posh-:--:--:--:--:--:--:--:--:
+..+..+.posh+..+..+..+..+..+..+..+..+..+
:--:--posh--:--:poshposhposhposhposh:--:
+..+posh.+..+..+poshposhposhposhposh+..+
:--:--:--:--:--:--:--:--:--:--:--:--:--:
さっき作成したファンクションの各行の先頭に、ロゴとなる文を一行ずつ、あれ今何文字目だっけとか、ん?1文字多いかなとか、あれ?今何をしてるんだったっけ、とかいう考えを必死で抑え、ただただ機械の様にやっていきます。
function netch(){
$wmi1 = Get-WmiObject -Class Win32_Processor
$cpu = $wmi1.Name
$wmi2 = Get-WmiObject -Class Win32_OperatingSystem
$os = $wmi2.Caption + " " + $wmi2.Version
$wmi3 = Get-WmiObject Win32_BaseBoard
$motherboard = $wmi3.Product + " " + $wmi1.SocketDesignation
$wmi4 = Get-WmiObject Win32_ComputerSystemProduct
$model = $wmi4.Vendor + $wmi4.Name
$wmi5 = Get-WmiObject Win32_PhysicalMemory
$m_capa = $wmi5.Capacity
$memory = ""
$flag = $false
foreach($buf in $m_capa){
if($flag){
$memory += " / "
}else{
$flag = $true
}
$m_size = [long]$buf
$m_size = [math]::Round($m_size / 1000000000, 2)
$memory += [string]$m_size + "Gb"
}
$wmi6 = Get-WmiObject Win32_DiskDrive
$disk = ""
$flag = $false
foreach($buf in $wmi6){
if($flag){
$disk += " / "
}else{
$flag = $true
}
$d_size = [long]$buf.Size
if($d_size -ge 1000000000000){
$d_size = [math]::Round($d_size / 1000000000000, 2)
$disk += [string]$d_size + "Tb"
}else{
$d_size = [math]::Round($d_size / 1000000000, 2)
$disk += [string]$d_size + "Gb"
}
}
$gpu = Get-CimInstance CIM_VideoController
$gpu_name = $gpu.Name
$locale = Get-WinSystemLocale
$locale_name = $locale.Name + " " + $locale.DisplayName
$shell = "PowerShell " + $PSversiontable.PSVersion
Write-Host ""
# ここからやっていきます。各行の前半をロゴの文、後半に Computer 情報です。
# 文字列の間に -ForegroundColor "色" を入れて、ロゴの中の色を変えています。
# 一旦配列に入れてーとかも考えましたが、余計ややこしくなりそうだったので止めました。
Write-Host " :--:--:--:--:--:--:--:--:--:--:--:--:--:" -ForegroundColor "Blue" -NoNewline; Write-Host " " $env:USERNAME -ForegroundColor "Green"
Write-Host " +..+" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ".+..+..+..+..+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline;Write-Host "------------------------------------------------------------" -ForegroundColor "White"
Write-Host " :--:--" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "--:--:--:--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "CPU: " -ForegroundColor "Cyan" -NoNewline; Write-Host $cpu -ForegroundColor "White"
Write-Host " +..+..+." -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "+..+..+..+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "OS: " -ForegroundColor "Cyan" -NoNewline; Write-Host $os -ForegroundColor "White"
Write-Host " :--:--:--:" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "-:--:--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Motherboard: " -ForegroundColor "Cyan" -NoNewline; Write-Host $motherboard -ForegroundColor "White"
Write-Host " +..+..+..+.." -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "..+..+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Model: " -ForegroundColor "Cyan" -NoNewline; Write-Host $model -ForegroundColor "White"
Write-Host " :--:--:--:--:-" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ":--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Memory: " -ForegroundColor "Cyan" -NoNewline; Write-Host $memory -ForegroundColor "White"
Write-Host " +..+..+..+..+..+" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ".+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Disk: " -ForegroundColor "Cyan" -NoNewline; Write-Host $disk -ForegroundColor "White"
Write-Host " :--:--:--:--:--:--" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Graphics: " -ForegroundColor "Cyan" -NoNewline; Write-Host $gpu_name -ForegroundColor "White"
Write-Host " +..+..+..+..+..+" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ".+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Locale: " -ForegroundColor "Cyan" -NoNewline; Write-Host $locale_name -ForegroundColor "White"
Write-Host " :--:--:--:--:-" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ":--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue" -NoNewline; Write-Host "Shell: " -ForegroundColor "Cyan" -NoNewline; Write-Host $shell -ForegroundColor "White"
Write-Host " +..+..+..+.." -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "..+..+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue"
Write-Host " :--:--:--:" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "-:--:--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue"
Write-Host " +..+..+." -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "+..+..+..+..+..+..+..+..+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host "" -ForegroundColor "DarkBlue"
Write-Host " :--:--" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host "--:--:" -ForegroundColor "Blue" -NoNewline; Write-Host "poshposhposhposhposh" -ForegroundColor "White" -NoNewline; Write-Host ":--: " -ForegroundColor "Blue"
Write-Host " +..+" -ForegroundColor "Blue" -NoNewline; Write-Host "posh" -ForegroundColor "White" -NoNewline; Write-Host ".+..+..+" -ForegroundColor "Blue" -NoNewline; Write-Host "poshposhposhposhposh" -ForegroundColor "White" -NoNewline; Write-Host "+..+ " -ForegroundColor "Blue" -NoNewline; Write-Host " " -BackgroundColor "Black" -NoNewline; Write-Host " " -BackgroundColor "DarkRed" -NoNewline; Write-Host " " -BackgroundColor "DarkGreen" -NoNewline; Write-Host " " -BackgroundColor "DarkYellow" -NoNewline; Write-Host " " -BackgroundColor "DarkBlue" -NoNewline; Write-Host " " -BackgroundColor "DarkMagenta" -NoNewline; Write-Host " " -BackgroundColor "DarkCyan" -NoNewline; Write-Host " " -BackgroundColor "Gray" -NoNewline; Write-Host ""
Write-Host " :--:--:--:--:--:--:--:--:--:--:--:--:--: " -ForegroundColor "Blue" -NoNewline; Write-Host " " -BackgroundColor "DarkGray" -NoNewline; Write-Host " " -BackgroundColor "Red" -NoNewline; Write-Host " " -BackgroundColor "Green" -NoNewline; Write-Host " " -BackgroundColor "Yellow" -NoNewline; Write-Host " " -BackgroundColor "Blue" -NoNewline; Write-Host " " -BackgroundColor "Magenta" -NoNewline; Write-Host " " -BackgroundColor "Cyan" -NoNewline; Write-Host " " -BackgroundColor "White" -NoNewline; Write-Host ""
Write-Host ""
$wmi1 = $wmi2 = $wmi3 = $wmi4 = $wmi5 = $wmi6 = $cpu = $os = $motherboard = $model = $memory = $disk = $gpu = $locale = $shell = $m_capa = $m_size = $flag = $d_size = $buf = $gpu_name = $locale_name = $null
[GC]::Collect()
}
ふぅ。
では、Microsoft.PowerShell_profile.ps1 を保存、Shellで再読み込みして最終テストです。
. $profile
netch
無事表示されました。何となく情報が乏しい感じがしますが、neofetch みたいなファンクションの完成です。
余談ですが、つい最近 素の ArchLinux の代わりに EndeavourOS をインストールしたので、早速 neofetch をインストールしようとしたのですが、なんと開発終了していました。
現在は Fastfetch というツールが受け継いで開発している様です。
やはり何かを継続するモチベーションを保つには、相当な力が必要みたいですね。そしてまた neofetch も筆者のような Linux 学習者にとって力の源でした。dylanarapsさん感謝です。