윈도우 서버 PowerShell 자동화 실전 가이드
윈도우 서버 관리에서 반복적인 작업은 시간과 에너지를 낭비합니다. PowerShell은 마이크로소프트가 제공하는 강력한 스크립팅 언어이자 쉘로, 윈도우 서버의 거의 모든 기능을 자동화할 수 있습니다. 이 글에서는 실무에서 바로 활용 가능한 PowerShell 자동화 스크립트를 소개합니다.
PowerShell 실행 정책 설정
PowerShell 스크립트를 실행하기 전에 먼저 실행 정책을 확인하고 설정해야 합니다.
# 현재 실행 정책 확인
Get-ExecutionPolicy
# 로컬 스크립트 실행 허용 (원격 스크립트는 서명 필요)
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# 관리자 권한으로 전체 시스템에 적용
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
시스템 정보 수집 자동화
기본 시스템 정보 조회
# 운영체제 정보
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, TotalPhysicalMemory
# CPU 정보
Get-WmiObject Win32_Processor | Select-Object Name, NumberOfCores, MaxClockSpeed
# 디스크 사용량 확인
Get-PSDrive -PSProvider FileSystem |
Select-Object Name, @{N='사용량(GB)';E={[math]::Round($_.Used/1GB,2)}},
@{N='여유공간(GB)';E={[math]::Round($_.Free/1GB,2)}},
@{N='전체(GB)';E={[math]::Round(($_.Used+$_.Free)/1GB,2)}}
서버 상태 보고서 자동 생성
# 서버 상태 보고서를 HTML 파일로 생성
$reportPath = "C:\Reports\server-status-$(Get-Date -Format 'yyyyMMdd').html"
$cpuLoad = (Get-WmiObject Win32_Processor).LoadPercentage
$memTotal = [math]::Round((Get-WmiObject Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
$memFree = [math]::Round((Get-WmiObject Win32_OperatingSystem).FreePhysicalMemory / 1MB, 2)
$html = @"
<html>
<body>
<h1>서버 상태 보고서 - $(Get-Date -Format 'yyyy-MM-dd HH:mm')</h1>
<p>CPU 사용률: $cpuLoad%</p>
<p>메모리: ${memFree}GB / ${memTotal}GB 여유</p>
</body>
</html>
"@
$html | Out-File -FilePath $reportPath -Encoding UTF8
Write-Host "보고서 생성 완료: $reportPath"
사용자 계정 일괄 관리
CSV 파일로 사용자 대량 생성
# users.csv 형식: Name,SamAccountName,Department,Password
Import-Csv "C:\users.csv" | ForEach-Object {
$securePassword = ConvertTo-SecureString $_.Password -AsPlainText -Force
New-LocalUser -Name $_.SamAccountName `
-Password $securePassword `
-FullName $_.Name `
-Description $_.Department `
-PasswordNeverExpires:$false
Add-LocalGroupMember -Group "Users" -Member $_.SamAccountName
Write-Host "사용자 생성 완료: $($_.SamAccountName)"
}
비활성 사용자 자동 비활성화
# 90일 이상 로그인하지 않은 계정 비활성화
$inactiveDays = 90
$cutoffDate = (Get-Date).AddDays(-$inactiveDays)
Get-ADUser -Filter {LastLogonDate -lt $cutoffDate -and Enabled -eq $true} `
-Properties LastLogonDate |
ForEach-Object {
Disable-ADAccount -Identity $_
Write-Host "비활성화: $($_.SamAccountName) (마지막 로그인: $($_.LastLogonDate))"
}
서비스 모니터링 및 자동 재시작
# 감시할 서비스 목록
$monitoredServices = @("W3SVC", "MSSQLSERVER", "WinRM")
foreach ($serviceName in $monitoredServices) {
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($null -eq $service) {
Write-Warning "서비스를 찾을 수 없음: $serviceName"
continue
}
if ($service.Status -ne "Running") {
Write-Host "서비스 재시작 중: $serviceName"
Start-Service -Name $serviceName
# 이벤트 로그에 기록
Write-EventLog -LogName Application `
-Source "PowerShell Monitoring" `
-EventId 1001 `
-EntryType Warning `
-Message "$serviceName 서비스가 중지되어 재시작했습니다."
} else {
Write-Host "$serviceName : 정상 실행 중"
}
}
로그 파일 자동 정리
# 30일 이상 된 로그 파일 자동 삭제
$logPath = "C:\Windows\Logs"
$daysToKeep = 30
$cutoffDate = (Get-Date).AddDays(-$daysToKeep)
$deletedFiles = Get-ChildItem -Path $logPath -Recurse -File |
Where-Object { $_.LastWriteTime -lt $cutoffDate -and $_.Extension -in @('.log', '.txt') } |
ForEach-Object {
$fileSize = [math]::Round($_.Length / 1KB, 2)
Remove-Item $_.FullName -Force
"$($_.Name) ($fileSize KB)"
}
Write-Host "삭제된 파일 수: $($deletedFiles.Count)"
$deletedFiles | ForEach-Object { Write-Host " - $_" }
백업 자동화
# 중요 디렉토리를 날짜별 폴더에 백업
function Backup-ServerData {
param(
[string]$SourcePath,
[string]$BackupRoot,
[int]$RetentionDays = 14
)
$dateStamp = Get-Date -Format "yyyy-MM-dd"
$backupPath = Join-Path $BackupRoot $dateStamp
# 백업 디렉토리 생성
if (-not (Test-Path $backupPath)) {
New-Item -ItemType Directory -Path $backupPath | Out-Null
}
# 파일 복사
Copy-Item -Path $SourcePath -Destination $backupPath -Recurse -Force
Write-Host "백업 완료: $backupPath"
# 오래된 백업 정리
Get-ChildItem -Path $BackupRoot -Directory |
Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$RetentionDays) } |
ForEach-Object {
Remove-Item $_.FullName -Recurse -Force
Write-Host "오래된 백업 삭제: $($_.Name)"
}
}
# 사용 예시
Backup-ServerData -SourcePath "C:\InetPub\wwwroot" `
-BackupRoot "D:\Backups\Web" `
-RetentionDays 14
작업 스케줄러 등록
PowerShell 스크립트를 작업 스케줄러에 등록하여 정기적으로 실행합니다.
# 매일 새벽 2시에 백업 스크립트 실행
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NonInteractive -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
$settings = New-ScheduledTaskSettingsSet `
-StartWhenAvailable `
-RunOnlyIfNetworkAvailable:$false
Register-ScheduledTask `
-TaskName "DailyBackup" `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-RunLevel Highest `
-Force
Write-Host "작업 스케줄러 등록 완료"
원격 서버 일괄 관리
# 여러 서버에 동시에 명령 실행
$servers = @("WEB01", "WEB02", "DB01", "APP01")
$results = Invoke-Command -ComputerName $servers -ScriptBlock {
[PSCustomObject]@{
ServerName = $env:COMPUTERNAME
OS = (Get-WmiObject Win32_OperatingSystem).Caption
CPU = (Get-WmiObject Win32_Processor).LoadPercentage
FreeDiskGB = [math]::Round(
(Get-PSDrive C).Free / 1GB, 2
)
Uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
}
}
$results | Format-Table -AutoSize
# CSV로 저장
$results | Export-Csv "C:\Reports\server-health-$(Get-Date -Format 'yyyyMMdd').csv" `
-NoTypeInformation -Encoding UTF8
PowerShell 모듈 관리
# PowerShellGet으로 유용한 모듈 설치
Install-Module -Name PSWindowsUpdate -Scope AllUsers -Force
Install-Module -Name Az -Scope AllUsers -AllowClobber -Force # Azure 관리
Install-Module -Name dbatools -Scope AllUsers -Force # SQL Server 관리
# 설치된 모듈 확인
Get-Module -ListAvailable | Select-Object Name, Version | Sort-Object Name
# Windows Update 자동화 (PSWindowsUpdate 사용)
Import-Module PSWindowsUpdate
Get-WindowsUpdate -AcceptAll -Install -AutoReboot
PowerShell 자동화는 윈도우 서버 관리의 효율을 크게 높여줍니다. 스크립트를 처음 작성할 때는 -WhatIf 매개변수를 활용해 실제 변경 없이 동작을 미리 확인하는 습관을 들이세요. 또한 스크립트를 Git으로 버전 관리하면 변경 이력을 추적하고 팀원과 공유하기 쉬워집니다. 작은 자동화부터 시작해 점차 범위를 넓혀가는 것이 실용적인 접근 방식입니다.
댓글남기기