Difference between revisions of "PowerShell Scripts"

From Hostek.com Wiki
Jump to: navigation, search
 
(7 intermediate revisions by the same user not shown)
Line 96: Line 96:
  
  
==Take Ownership of Directory and All Sub-Files/Sub-Directories==
+
==Scheduled Service Restart Script==
  
This script allows you to recursively take ownership of a directory and all of its sub-files/sub-directoriesThis is sometimes necessary if you accidentally remove your own permissions from a directory and need to give yourself permissions again.  You must be logged in as an administrator for this to work.
+
This script can be used to restart a service via a scheduled taskThe 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">
 
<syntaxhighlight lang="powershell">
param(
+
$ServiceName = 'Name of Service' # NAME OF SERVICE TO RESTART
    [string]$Directory = $(throw 'Parameter ''Directory'' is required.')
+
$ProcessName = 'ServiceProcessName.exe' # NAME OF PROCESS TO KILL IF SERVICE FAILS TO STOP
)
+
  
$Directory = $Directory.Replace('\', '\\')
+
$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
  
if ($dir32 = gwmi win32_directory -filter "Name=""$Directory""") {
+
# GET SERVICE
     $dir32.TakeOwnerShipEx($null, $true)
+
$Service = Get-Service $ServiceName
} else {
+
 
     throw "The specified directory does not exist: $Directory."
+
#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>
 
</syntaxhighlight>
  
 
Example Usage:
 
Example Usage:
 +
powershell -File Restart-Service.ps1
 +
 +
 +
==Task Scheduling Commands==
  
  powershell -File TakeOwnership.ps1 C:\FULL\PATH\TO\DIRECTORY
+
===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:05, 10 June 2013 (CDT)
+
[[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.

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

Davidd (talk) 15:17, 10 June 2013 (CDT)