「関数の中で設定した変数が、外で使えない!」 「スクリプト全体で共有したい値があるのに…」 「グローバル変数って聞くけど、どう使うの?」
PowerShellでスクリプトを書いていると、こんな悩みに直面することがありますよね。
実は、PowerShellの変数には「スコープ」という概念があり、変数が使える範囲が決まっているんです。グローバル変数を理解すれば、スクリプト全体で値を共有したり、関数間でデータを受け渡したりが自在にできるようになります。
今回は、PowerShellのグローバル変数について、基本から実践的な使い方まで、分かりやすく解説していきます!
PowerShellの変数スコープとは?

スコープの基本概念
スコープとは、変数が有効な範囲のことです。
部屋に例えると:
- ローカルスコープ = 自分の部屋(その場所でのみ有効)
- スクリプトスコープ = 家全体(スクリプト内で有効)
- グローバルスコープ = 街全体(PowerShellセッション全体で有効)
PowerShellの4つのスコープ
# スコープの種類と優先順位(上から順に狭い範囲)
1. Local(ローカル) # 現在の場所のみ
2. Script(スクリプト) # スクリプトファイル内
3. Global(グローバル) # PowerShellセッション全体
4. Private(プライベート)# 子スコープから見えない
スコープの確認方法:
# 現在のスコープを確認
Get-Variable -Scope Local
Get-Variable -Scope Global
Get-Variable -Scope Script
グローバル変数の作成と使用方法
基本的な作成方法
方法1:$global:プレフィックスを使う
# グローバル変数の作成
$global:MyGlobalVar = "これはグローバル変数です"
# グローバル変数の参照
Write-Host $global:MyGlobalVar
# 通常の参照でもアクセス可能
Write-Host $MyGlobalVar
方法2:New-Variableコマンドレットを使う
# コマンドレットでグローバル変数を作成
New-Variable -Name "AppConfig" -Value "Production" -Scope Global
# オプション付きで作成(読み取り専用)
New-Variable -Name "AppVersion" -Value "1.0.0" -Scope Global -Option ReadOnly
ローカル変数との違いを理解する
# 実験:スコープの違いを確認
function Test-Scope {
# ローカル変数(関数内のみ有効)
$localVar = "ローカル変数"
# グローバル変数(どこでも有効)
$global:globalVar = "グローバル変数"
Write-Host "関数内 - ローカル: $localVar"
Write-Host "関数内 - グローバル: $globalVar"
}
# 関数を実行
Test-Scope
# 関数の外で確認
Write-Host "関数外 - ローカル: $localVar" # 空(アクセス不可)
Write-Host "関数外 - グローバル: $globalVar" # 表示される
グローバル変数の実践的な使い方
設定値の管理
# アプリケーション全体の設定をグローバル変数で管理
function Initialize-AppSettings {
$global:AppSettings = @{
DatabaseServer = "localhost\SQLEXPRESS"
LogPath = "C:\Logs"
DebugMode = $true
MaxRetries = 3
Timeout = 30
}
Write-Host "アプリケーション設定を初期化しました" -ForegroundColor Green
}
# 設定を使う関数
function Write-AppLog {
param([string]$Message)
if ($global:AppSettings.DebugMode) {
$logFile = Join-Path $global:AppSettings.LogPath "app_$(Get-Date -Format 'yyyyMMdd').log"
$logEntry = "$(Get-Date -Format 'HH:mm:ss'): $Message"
Add-Content -Path $logFile -Value $logEntry
Write-Host $logEntry -ForegroundColor Yellow
}
}
# 使用例
Initialize-AppSettings
Write-AppLog "アプリケーションを開始しました"
カウンターや累積値の管理
# 処理回数をカウントするグローバル変数
$global:ProcessCount = 0
$global:ErrorCount = 0
$global:SuccessCount = 0
function Process-Item {
param([string]$Item)
$global:ProcessCount++
try {
# 何かの処理
if ($Item -match "error") {
throw "エラーが発生しました"
}
Write-Host "処理成功: $Item" -ForegroundColor Green
$global:SuccessCount++
}
catch {
Write-Host "処理失敗: $Item - $_" -ForegroundColor Red
$global:ErrorCount++
}
}
# 複数アイテムを処理
@("item1", "error_item", "item3", "error_item2", "item5") | ForEach-Object {
Process-Item $_
}
# 結果を表示
Write-Host "`n処理結果:"
Write-Host "総処理数: $global:ProcessCount"
Write-Host "成功: $global:SuccessCount" -ForegroundColor Green
Write-Host "失敗: $global:ErrorCount" -ForegroundColor Red
複数スクリプト間での値共有
Script1.ps1:
# データを収集してグローバル変数に保存
$global:CollectedData = @()
function Collect-SystemInfo {
$info = @{
ComputerName = $env:COMPUTERNAME
OS = (Get-CimInstance Win32_OperatingSystem).Caption
Memory = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB
Timestamp = Get-Date
}
$global:CollectedData += $info
Write-Host "システム情報を収集しました"
}
Collect-SystemInfo
Script2.ps1:
# 別のスクリプトから、グローバル変数のデータを利用
function Export-CollectedData {
if ($global:CollectedData) {
$global:CollectedData | Export-Csv -Path "C:\Reports\system_info.csv" -NoTypeInformation
Write-Host "データをエクスポートしました"
} else {
Write-Host "エクスポートするデータがありません" -ForegroundColor Yellow
}
}
Export-CollectedData
環境変数との違いと使い分け

環境変数とグローバル変数の比較
# 環境変数(システム全体またはユーザー全体で永続的)
$env:MY_ENV_VAR = "環境変数の値"
[Environment]::SetEnvironmentVariable("MY_ENV_VAR", "環境変数の値", "User")
# グローバル変数(PowerShellセッション内のみ)
$global:MY_GLOBAL_VAR = "グローバル変数の値"
# 違いを確認
Write-Host "環境変数: $env:MY_ENV_VAR"
Write-Host "グローバル変数: $global:MY_GLOBAL_VAR"
# 新しいPowerShellウィンドウを開くと...
# 環境変数は残っているが、グローバル変数は消えている
使い分けの指針
環境変数を使うべき場合:
- システム設定(PATH、TEMP など)
- 複数のアプリケーション間で共有
- PowerShellセッション終了後も保持したい
グローバル変数を使うべき場合:
- スクリプト実行中のみ必要な値
- 一時的な設定やカウンター
- セッション内での作業データ
グローバル変数のベストプラクティス
命名規則を決める
# 良い例:プレフィックスで用途を明確に
$global:CONFIG_DatabasePath = "C:\Database"
$global:TEMP_ProcessingData = @()
$global:APP_Version = "2.0.1"
# グローバル変数用のプレフィックス例
# CONFIG_ : 設定値
# TEMP_ : 一時データ
# APP_ : アプリケーション情報
# LOG_ : ログ関連
初期化関数を作る
function Initialize-GlobalVariables {
[CmdletBinding()]
param()
# 既存の値をクリア(オプション)
if ($global:APP_Initialized) {
Write-Host "グローバル変数は既に初期化されています" -ForegroundColor Yellow
return
}
# グローバル変数を初期化
$global:APP_Initialized = $true
$global:APP_StartTime = Get-Date
$global:APP_Config = @{
Version = "1.0.0"
Environment = "Development"
MaxThreads = 4
}
$global:APP_Statistics = @{
TotalRuns = 0
Errors = @()
LastRun = $null
}
Write-Host "グローバル変数を初期化しました" -ForegroundColor Green
Write-Host "バージョン: $($global:APP_Config.Version)"
Write-Host "環境: $($global:APP_Config.Environment)"
}
# スクリプトの最初で呼び出す
Initialize-GlobalVariables
クリーンアップを忘れない
function Clear-GlobalVariables {
# 特定のプレフィックスを持つグローバル変数をクリア
Get-Variable -Scope Global | Where-Object {
$_.Name -match "^(APP_|TEMP_|CONFIG_)"
} | ForEach-Object {
Remove-Variable -Name $_.Name -Scope Global -Force -ErrorAction SilentlyContinue
Write-Host "削除: $($_.Name)" -ForegroundColor Gray
}
Write-Host "グローバル変数をクリーンアップしました" -ForegroundColor Green
}
# スクリプトの最後やエラー時に実行
try {
# メイン処理
} finally {
Clear-GlobalVariables
}
よくあるトラブルと解決方法
トラブル1:変数が見つからない
問題:
function Set-Value {
$myVar = "テスト" # ローカル変数になってしまう
}
Set-Value
Write-Host $myVar # 空
解決:
function Set-Value {
$global:myVar = "テスト" # グローバル変数として設定
}
Set-Value
Write-Host $myVar # "テスト"が表示される
トラブル2:予期しない値の上書き
問題を防ぐ方法:
# 読み取り専用のグローバル変数を作成
New-Variable -Name "CONST_MaxSize" -Value 100 -Scope Global -Option ReadOnly
# 定数として扱う(変更不可)
try {
$global:CONST_MaxSize = 200 # エラーになる
} catch {
Write-Host "定数は変更できません: $_" -ForegroundColor Red
}
トラブル3:モジュール間での変数共有
# モジュール内でグローバル変数を設定
# MyModule.psm1
function Set-ModuleGlobal {
$global:ModuleData = "モジュールから設定"
# モジュール変数(モジュール内のみ)
$script:ModuleInternal = "内部データ"
}
# メインスクリプト
Import-Module .\MyModule.psm1
Set-ModuleGlobal
Write-Host $global:ModuleData # アクセス可能
Write-Host $script:ModuleInternal # アクセス不可
実践例:プロジェクト管理スクリプト
完全な実装例
# プロジェクト管理用グローバル変数システム
# 初期化
function Initialize-ProjectManager {
$global:PROJECT = @{
Name = "MyProject"
Tasks = @()
TeamMembers = @()
StartDate = Get-Date
Status = "Active"
Statistics = @{
TotalTasks = 0
CompletedTasks = 0
PendingTasks = 0
}
}
Write-Host "プロジェクト管理システムを初期化しました" -ForegroundColor Green
}
# タスク追加
function Add-ProjectTask {
param(
[string]$TaskName,
[string]$Assignee,
[string]$Priority = "Normal"
)
$task = @{
ID = $global:PROJECT.Statistics.TotalTasks + 1
Name = $TaskName
Assignee = $Assignee
Priority = $Priority
Status = "Pending"
CreatedDate = Get-Date
}
$global:PROJECT.Tasks += $task
$global:PROJECT.Statistics.TotalTasks++
$global:PROJECT.Statistics.PendingTasks++
Write-Host "タスクを追加: #$($task.ID) - $TaskName" -ForegroundColor Cyan
}
# タスク完了
function Complete-ProjectTask {
param([int]$TaskID)
$task = $global:PROJECT.Tasks | Where-Object { $_.ID -eq $TaskID }
if ($task) {
$task.Status = "Completed"
$task.CompletedDate = Get-Date
$global:PROJECT.Statistics.CompletedTasks++
$global:PROJECT.Statistics.PendingTasks--
Write-Host "タスク完了: #$TaskID - $($task.Name)" -ForegroundColor Green
} else {
Write-Host "タスクが見つかりません: #$TaskID" -ForegroundColor Red
}
}
# レポート表示
function Show-ProjectReport {
Write-Host "`n===== プロジェクトレポート =====" -ForegroundColor Yellow
Write-Host "プロジェクト名: $($global:PROJECT.Name)"
Write-Host "ステータス: $($global:PROJECT.Status)"
Write-Host "開始日: $($global:PROJECT.StartDate.ToString('yyyy/MM/dd'))"
Write-Host ""
Write-Host "タスク統計:"
Write-Host " 総タスク数: $($global:PROJECT.Statistics.TotalTasks)"
Write-Host " 完了: $($global:PROJECT.Statistics.CompletedTasks)" -ForegroundColor Green
Write-Host " 保留中: $($global:PROJECT.Statistics.PendingTasks)" -ForegroundColor Yellow
if ($global:PROJECT.Statistics.TotalTasks -gt 0) {
$completionRate = ($global:PROJECT.Statistics.CompletedTasks / $global:PROJECT.Statistics.TotalTasks) * 100
Write-Host " 完了率: $([math]::Round($completionRate, 1))%"
}
Write-Host "`nタスク一覧:"
$global:PROJECT.Tasks | ForEach-Object {
$statusColor = if ($_.Status -eq "Completed") { "Green" } else { "Gray" }
Write-Host " #$($_.ID): $($_.Name) [$($_.Assignee)] - $($_.Status)" -ForegroundColor $statusColor
}
}
# 使用例
Initialize-ProjectManager
Add-ProjectTask -TaskName "要件定義" -Assignee "田中" -Priority "High"
Add-ProjectTask -TaskName "設計書作成" -Assignee "佐藤" -Priority "High"
Add-ProjectTask -TaskName "実装" -Assignee "鈴木" -Priority "Normal"
Complete-ProjectTask -TaskID 1
Show-ProjectReport
PowerShell ISEやVS Codeでの注意点

デバッグ時の動作
# ISEやVS Codeでは、セッションが継続される
# 同じグローバル変数が残り続けることがある
# デバッグ前にクリアする習慣
function Reset-DebugEnvironment {
# すべてのカスタムグローバル変数を削除
Get-Variable -Scope Global | Where-Object {
$_.Name -notin @('PSVersionTable', 'PSScriptRoot', 'PSCommandPath',
'Host', 'HOME', 'ExecutionContext', 'Error')
} | Where-Object {
-not $_.Name.StartsWith('$')
} | ForEach-Object {
Remove-Variable -Name $_.Name -Scope Global -Force -ErrorAction SilentlyContinue
}
Write-Host "デバッグ環境をリセットしました" -ForegroundColor Cyan
}
まとめ – グローバル変数を正しく使いこなそう
PowerShellのグローバル変数について、基本から実践まで理解できましたか?
押さえておくべきポイント
✅ **$global:**プレフィックスで、どこからでもアクセス可能な変数を作成
✅ スコープの理解が、変数管理の基本
✅ 命名規則を決めて、管理しやすくする
✅ 初期化とクリーンアップで、クリーンな環境を保つ
グローバル変数が適している場面
- 設定値の一元管理
- スクリプト全体での状態管理
- 関数間でのデータ共有
- カウンターや統計情報の収集
今すぐ実践できること
- 既存スクリプトの変数スコープを見直す
- 設定値をグローバル変数で管理する
- 命名規則を決めて適用する
- 初期化・クリーンアップ関数を作成する
グローバル変数を適切に使いこなせば、より柔軟で保守しやすいPowerShellスクリプトが書けるようになります。ぜひ今日から実践してみてください!
コメント