Difference between revisions of "PowerShell Scripts"
(→Disk Usage Warning) |
|||
(9 intermediate revisions by the same user not shown) | |||
Line 41: | Line 41: | ||
This script will gzip compress all files within a folder. The original file will be replaced with a .gz file starting with the same name. This can be useful for compressing SQL backups or Log files on a schedule. | This script will gzip compress all files within a folder. The original file will be replaced with a .gz file starting with the same name. This can be useful for compressing SQL backups or Log files on a schedule. | ||
+ | |||
+ | Optional parameter '''Days''' specifies how many days old a file must be in order to be gzipped. This is useful for log folders where you may want the last couple days to remain unzipped | ||
+ | |||
+ | Option switch '''-Recurse''' allows the script to include all sub-directories. | ||
<syntaxhighlight lang="powershell"> | <syntaxhighlight lang="powershell"> | ||
− | + | param( | |
− | + | [string]$Directory = $(throw 'Parameter ''Directory'' is required.'), | |
− | + | [int]$Days = 0, | |
− | + | [switch]$Recurse = $false | |
− | + | ) | |
− | + | ||
− | + | $Date = [System.DateTime]::Now.AddDays($Days * -1) | |
− | + | ||
− | + | if ($(Test-Path $Directory) -eq $false) { | |
− | + | throw "Directory does not exist: $Directory" | |
− | + | } | |
− | + | ||
− | + | foreach ($file in $(Get-ChildItem -Path $Directory -File -Recurse:$Recurse|Where-Object {$_.Name -match '^(?!.*\.gz$)' -and $_.LastWriteTime -lt $Date})) { | |
− | + | $fsFile = New-Object System.IO.FileStream ($file.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read); | |
− | + | $fsGZip = New-Object System.IO.FileStream ("$($file.FullName).gz", [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None) | |
− | + | $gzSream = New-Object System.IO.Compression.GzipStream ($fsGZip, [IO.Compression.CompressionMode]::Compress) | |
− | + | ||
− | + | $gzipped = $false | |
− | + | ||
− | + | try { | |
− | + | ||
− | + | $BUFFER_SIZE = 1024 * 256 | |
− | + | $buffer = New-Object byte[]($BUFFER_SIZE); | |
− | + | $bytesRead = -1 | |
− | + | ||
− | + | while ($bytesRead -ne 0) { | |
− | + | $bytesRead = $fsFile.Read($buffer, 0, $BUFFER_SIZE) | |
− | + | $gzSream.Write($buffer, 0, $bytesRead) | |
− | + | } | |
− | + | ||
− | + | $gzipped = $true | |
− | + | } | |
− | + | finally { | |
− | + | $gzSream.Dispose(); | |
− | + | $fsGZip.Dispose(); | |
− | + | $fsFile.Dispose(); | |
− | + | } | |
− | + | ||
+ | if ($gzipped) { | ||
+ | Remove-Item $file.FullName | ||
+ | } | ||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Example Usage: | Example Usage: | ||
− | powershell -File GZipDirContents.ps1 C:\FULL\PATH\TO\DIRECTORY | + | powershell -File GZipDirContents.ps1 C:\FULL\PATH\TO\DIRECTORY 1 -Recurse |
+ | |||
+ | |||
+ | ==Scheduled Service Restart Script== | ||
+ | |||
+ | This script can be used to restart a service via a scheduled task. The script will kill the process if the service does not stop within 60 seconds, and it will send an e-mail notification if the service does not start back up within 120 seconds and continue attempting starts every 120 seconds and sending additional notifications. | ||
+ | |||
+ | <syntaxhighlight lang="powershell"> | ||
+ | $ServiceName = 'Name of Service' # NAME OF SERVICE TO RESTART | ||
+ | $ProcessName = 'ServiceProcessName.exe' # NAME OF PROCESS TO KILL IF SERVICE FAILS TO STOP | ||
+ | |||
+ | $ServerName = 'svr1.servername.com' # NAME OF SERVER FOR WARNING EMAIL IF SERVICE FAILS TO START | ||
+ | $EmailFrom = "autoservicerestart@$ServerName" # FROM ADDRESS FOR WARNING EMAIL IF SERVICE FAILS TO START | ||
+ | $EmailTo = 'address@your-mail-domain.com' # TO ADDRESS FOR WARNING EMAIL IF SERVICE FAILS TO START | ||
+ | |||
+ | # GET SERVICE | ||
+ | $Service = Get-Service $ServiceName | ||
+ | |||
+ | #VERIFY SERVICE IS RUNNING | ||
+ | if ($Service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) { | ||
+ | |||
+ | #INITIATE SERVICE STOP | ||
+ | $Service|Stop-Service | ||
+ | |||
+ | #WAIT UP TO 60 SECONDS FOR STOP | ||
+ | $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped, [System.TimeSpan]::Parse('00:01:00')) | ||
+ | |||
+ | #REFRESH SERVICE STATUS | ||
+ | $Service.Refresh() | ||
+ | |||
+ | #CHECK IF SERVICE DID NOT SUCCESSFULLY STOP | ||
+ | if ($Service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Stopped) { | ||
+ | |||
+ | #KILL SERVICE PROCSES | ||
+ | Stop-Process -Name $ProcessName -Force | ||
+ | |||
+ | #WAIT UP TO 5 SECONDS FOR SERVICE STATUS TO UPDATE | ||
+ | $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped, [System.TimeSpan]::Parse('00:00:05')) | ||
+ | |||
+ | #REFRESH SERVICE STATUS | ||
+ | $Service.Refresh() | ||
+ | } | ||
+ | |||
+ | #ATTEMPT TO START SERVICE | ||
+ | $Service.Start() | ||
+ | |||
+ | #WAIT UP TO 120 SECONDS FOR START | ||
+ | $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [System.TimeSpan]::Parse('00:02:00')) | ||
+ | |||
+ | #REFRESH SERVICE STATUS | ||
+ | $Service.Refresh() | ||
+ | |||
+ | $smtp = $null | ||
+ | #CHECK IF SERVICE HAS STARTED AND RUN THE FOLLOWING UNTIL IT HAS | ||
+ | while ($Service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Running) { | ||
+ | if ($smtp -eq $null) { | ||
+ | $smtp = new-object Net.Mail.SmtpClient('localhost') | ||
+ | } | ||
+ | |||
+ | $smtp.Send($EmailFrom, $EmailTo, "Automated Service Restart Warning: $ServiceName", "Service '$ServiceName' has been configured to automatically restart on a schedule. It failed to start back up at $([System.DateTime]::Now) during the scheduled restart. Please check the service and verify that it starts back up.") | ||
+ | |||
+ | #ATTEMPT TO START SERVICE | ||
+ | $Service.Start() | ||
+ | |||
+ | #WAIT UP TO 120 SECONDS FOR START | ||
+ | $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [System.TimeSpan]::Parse('00:02:00')) | ||
+ | |||
+ | #REFRESH SERVICE STATUS | ||
+ | $Service.Refresh() | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Example Usage: | ||
+ | powershell -File Restart-Service.ps1 | ||
+ | |||
+ | |||
+ | ==Task Scheduling Commands== | ||
+ | |||
+ | ===Schedule to run at 2:00 AM daily=== | ||
+ | schtasks /create /tn "Task Name" /tr "PowerShell -File C:\Scripts\Script.ps1" /sc daily /st 02:00:00 /RU System | ||
+ | |||
+ | ===Schedule to run at 2:00 AM Sunday mornings=== | ||
+ | schtasks /create /tn "Task Name" /tr "PowerShell -File C:\Scripts\Script.ps1" /sc weekly /d SUN /st 02:00:00 /RU System | ||
+ | ---- | ||
+ | [[User:Davidd|Davidd]] ([[User talk:Davidd|talk]]) 15:17, 10 June 2013 (CDT) | ||
[[Category:VPS]] | [[Category:VPS]] | ||
+ | __FORCETOC__ |
Latest revision as of 20:20, 19 August 2013
This is a repository of PowerShell Scripts for server management tasks.
Contents
Disk Usage Warning
This script allows you to send an e-mail if disk free-space is below a particular percentage.
#SETTINGS $Computers = 'server1' # multiple servers should be formmated: 'server1', 'server2', 'server3'. The user executing this script must have administrative access to all servers. $WarnPercentage = 15 $SmtpHost = 'mail.domainname.com' $SmtpPort = 25 $FromAddress = 'disk-monitor@domainname.com' $Recipients = 'admin@domainname.com' # multiple recipients should be separated with commas: 'user1@domainname.com,user2@domainname.com,user3@domainname.com' #SETTINGS #GET DISK OVERAGES $Overages = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" -ComputerName $Computers| ` Where { (100 * ($_.FreeSpace / $_.Size)) -le $WarnPercentage }| ` Select SystemName, DeviceID, @{ Name="FreeSpace(GB)"; Expression={"{0:N}" -f ($_.FreeSpace / 1GB) }} $OverageCount = @($Overages).Length #GET DISK OVERAGES if ($OverageCount -gt 0) { #SEND EMAIL $Subject = "$OverageCount drives are below $WarnPercentage% free space" $Body = "Warning, the following drives are below $WarnPercentage% free space:`r`n`r`n$($Overages|Out-String -Width 80)" $SmtpClient = New-Object System.Net.Mail.SmtpClient($SmtpHost, $SmtpPort) $SmtpClient.Send($FromAddress, $Recipients, $Subject, $Body) $SmtpClient.Dispose() #SEND EMAIL }
Example Usage:
powershell -File CheckDiskUsage.ps1
GZip All Files in Directory
This script will gzip compress all files within a folder. The original file will be replaced with a .gz file starting with the same name. This can be useful for compressing SQL backups or Log files on a schedule.
Optional parameter Days specifies how many days old a file must be in order to be gzipped. This is useful for log folders where you may want the last couple days to remain unzipped
Option switch -Recurse allows the script to include all sub-directories.
param( [string]$Directory = $(throw 'Parameter ''Directory'' is required.'), [int]$Days = 0, [switch]$Recurse = $false ) $Date = [System.DateTime]::Now.AddDays($Days * -1) if ($(Test-Path $Directory) -eq $false) { throw "Directory does not exist: $Directory" } foreach ($file in $(Get-ChildItem -Path $Directory -File -Recurse:$Recurse|Where-Object {$_.Name -match '^(?!.*\.gz$)' -and $_.LastWriteTime -lt $Date})) { $fsFile = New-Object System.IO.FileStream ($file.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read); $fsGZip = New-Object System.IO.FileStream ("$($file.FullName).gz", [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None) $gzSream = New-Object System.IO.Compression.GzipStream ($fsGZip, [IO.Compression.CompressionMode]::Compress) $gzipped = $false try { $BUFFER_SIZE = 1024 * 256 $buffer = New-Object byte[]($BUFFER_SIZE); $bytesRead = -1 while ($bytesRead -ne 0) { $bytesRead = $fsFile.Read($buffer, 0, $BUFFER_SIZE) $gzSream.Write($buffer, 0, $bytesRead) } $gzipped = $true } finally { $gzSream.Dispose(); $fsGZip.Dispose(); $fsFile.Dispose(); } if ($gzipped) { Remove-Item $file.FullName } }
Example Usage:
powershell -File GZipDirContents.ps1 C:\FULL\PATH\TO\DIRECTORY 1 -Recurse
Scheduled Service Restart Script
This script can be used to restart a service via a scheduled task. The script will kill the process if the service does not stop within 60 seconds, and it will send an e-mail notification if the service does not start back up within 120 seconds and continue attempting starts every 120 seconds and sending additional notifications.
$ServiceName = 'Name of Service' # NAME OF SERVICE TO RESTART $ProcessName = 'ServiceProcessName.exe' # NAME OF PROCESS TO KILL IF SERVICE FAILS TO STOP $ServerName = 'svr1.servername.com' # NAME OF SERVER FOR WARNING EMAIL IF SERVICE FAILS TO START $EmailFrom = "autoservicerestart@$ServerName" # FROM ADDRESS FOR WARNING EMAIL IF SERVICE FAILS TO START $EmailTo = 'address@your-mail-domain.com' # TO ADDRESS FOR WARNING EMAIL IF SERVICE FAILS TO START # GET SERVICE $Service = Get-Service $ServiceName #VERIFY SERVICE IS RUNNING if ($Service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) { #INITIATE SERVICE STOP $Service|Stop-Service #WAIT UP TO 60 SECONDS FOR STOP $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped, [System.TimeSpan]::Parse('00:01:00')) #REFRESH SERVICE STATUS $Service.Refresh() #CHECK IF SERVICE DID NOT SUCCESSFULLY STOP if ($Service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Stopped) { #KILL SERVICE PROCSES Stop-Process -Name $ProcessName -Force #WAIT UP TO 5 SECONDS FOR SERVICE STATUS TO UPDATE $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped, [System.TimeSpan]::Parse('00:00:05')) #REFRESH SERVICE STATUS $Service.Refresh() } #ATTEMPT TO START SERVICE $Service.Start() #WAIT UP TO 120 SECONDS FOR START $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [System.TimeSpan]::Parse('00:02:00')) #REFRESH SERVICE STATUS $Service.Refresh() $smtp = $null #CHECK IF SERVICE HAS STARTED AND RUN THE FOLLOWING UNTIL IT HAS while ($Service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Running) { if ($smtp -eq $null) { $smtp = new-object Net.Mail.SmtpClient('localhost') } $smtp.Send($EmailFrom, $EmailTo, "Automated Service Restart Warning: $ServiceName", "Service '$ServiceName' has been configured to automatically restart on a schedule. It failed to start back up at $([System.DateTime]::Now) during the scheduled restart. Please check the service and verify that it starts back up.") #ATTEMPT TO START SERVICE $Service.Start() #WAIT UP TO 120 SECONDS FOR START $Service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [System.TimeSpan]::Parse('00:02:00')) #REFRESH SERVICE STATUS $Service.Refresh() } }
Example Usage:
powershell -File Restart-Service.ps1
Task Scheduling Commands
Schedule to run at 2:00 AM daily
schtasks /create /tn "Task Name" /tr "PowerShell -File C:\Scripts\Script.ps1" /sc daily /st 02:00:00 /RU System
Schedule to run at 2:00 AM Sunday mornings
schtasks /create /tn "Task Name" /tr "PowerShell -File C:\Scripts\Script.ps1" /sc weekly /d SUN /st 02:00:00 /RU System