Today I'm going to share something I've spent a lot of time working on -- the contents of this script are what made me so enthusiastic about PowerShell! When I first started as an Overnight Admin I was working alone and found myself receiving the same alerts either for the same computer over and over or for multiple different machines in multiple domains. This is when I found out about PowerShell -- and I started automating everything including pre-loading the cmdlets I use on a daily basis to the server that is always alerting by using a PowerShell $PROFILE.
Here it is, every time after running this script you will see the below cmdlets written verbosely within PowerShell whenever you open PowerShell.exe.
Here is a screen shot of the code with all the functions collapsed, as you can see there isn't too much going on other than added the functions. The rest of the code does is create a profile on the system you run it against and then add all of the code contained within the $NewPRODILE variable on line 2 into the newly created PowerShell Profile location at line 490-491.
Below is all the code in it's entirety....
$VerbosePreference = "Continue"
$NewPROFILE = {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
11\11\2013 updated: 3/27/2014
.Synopsis
Automating the world one line of code at a time.
.DESCRIPTION
This is my version of a PS $PROFILE made to be used as a startup GPO
.EXAMPLE
Type any cmdlet listed above to run the corresponding cmds.
PS C:\> Get-TopCpu
This cmdlet will output the hostname of the computer(s) the cmdlet is running `
agiast followed by an array of the top 10 utilizing CPU processes'
.NOTES
This is a gathering of all the primary functions I've developed over the last few months.
#>
Set-Location "$env:USERPROFILE\Desktop\"
$Host.PrivateData.VerboseForegroundColor = "Green"
$Host.PrivateData.VerboseBackgroundColor = "Black"
$VerbosePreference = "Continue" ; $ErrorActionPreference = "SilentlyContinue"
$uisettings = (Get-Host).UI.RawUI
$uisettings.WindowTitle = "$env:COMPUTERNAME :: $env:USERDNSDOMAIN\$env:USERNAME"
$uisettings.CursorSize = "100"
$b = $uisettings.WindowSize
$b.Width = 116
$b.Height = 50
$uisettings.WindowSize = $b
$s = $uisettings.BufferSize
$s.Width = 116
$s.Height = 3000
$uisettings.BufferSize = $s
$x = $uisettings.WindowPosition
$x.x = 0
$x.y = 0
$uisettings.WindowPosition = $x
$ErrorActionPreference = "Continue"
Write-Verbose "`t
`t (a) Get-Cpu ===> Gathers general CPU statistics
`t (b) Get-TopCpu ===> Gathers Top 10 CPU consuming processes
`t (c) Get-Memory ===> Gathers Memory\Pages/Sec. statistics
`t (d) Get-Uptime ===> Outputs how long since the last reboot
`t (e) Write-HTML ===> Creates a HTML file on the Desktop with the local computers info
`t (f) Get-Stopped ===> Finds Services set to start automatically but are stopped
`t (g) Get-FreeSpace ===> Gathers Disk Drive Available FreeSpace Percentage
`t (hh) Start-Cleanup ===> Automate cleaning up a C: drive with low disk space
`t (i) Get-Installed ===> Retrieve information related to all installed programs
`t (j) Get-PSknowledge ===> Get-Command | Get-Random | help -Examples | Out-String "
Set-Alias -Name a Get-Cpu
Set-Alias -Name b Get-TopCpu
Set-Alias -Name c Get-Memory
Set-Alias -Name d Get-Uptime
Set-Alias -Name e Write-HTML
Set-Alias -Name f Get-Stopped
Set-Alias -Name g Get-FreeSpace
Set-Alias -Name hh Start-Cleanup
Set-Alias -Name i Get-Installed
Set-Alias -Name j Get-PSknowledge
function Show-Commands { Start-Process powershell.exe -Verb RunAs }
$VerbosePreference = "silentlyContinue"
Function Get-Cpu {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
10\ 1\2013
.Synopsis
Gathers general CPU statistics
.DESCRIPTION
Gathers Computername, Date, lists the top 10 CPU consuming processes and then `
3 samples of the Average Processor time. and finally the average CPU usage.
.EXAMPLE
Get-Cpu -Computername localhost | ConvertTo-Html | Out-File C:\
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$Computername )
Begin { $Info = Get-Date ; Hostname }
Process { $Start = Get-Process | Sort-Object -Descending cpu | Select-Object -First 10 | Format-Table -AutoSize
$CpuTime = Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 1 -MaxSamples 3
$Cmd = wmic cpu get loadpercentage }
End { $Info
$Start | Format-Table -AutoSize
$CpuTime
$Cmd }
}
Function Get-TopCpu {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
10\25\2013
.Synopsis
Gathers Top 10 CPU consuming processes.
.DESCRIPTION
This function gathers all processes list them by highest CPU consumption and `
then displays a nice colorfull display of the top 10 processes listed decending.
.EXAMPLE
Get-TopCpu -computername localhost -color yellow
#>
[CmdletBinding()]
param ( [Parameter(ValueFromPipelineByPropertyName=$true,
Position=0)]
[string[]]$computername = $env:COMPUTERNAME,
[string]$color = "Green"
)
$num = 1
$Total = 10
$Cpu = Get-Process | Sort-Object CPU -Descending
Hostname
foreach ($_ in $Cpu) {
If ($num -gt $Total) { break }
write-host "$num) " -NoNewline
write-host $_.Description -ForegroundColor "$color" -NoNewline
write-host " - CPU:"$_.CPU
$num += 1 }
Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 1 -MaxSamples 3
Get-WmiObject win32_processor | select LoadPercentage | fl
}
Function Get-Memory {
<#A
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
11\19\2013
.Synopsis
Gathers Memory\Pages/Sec. statistics
.DESCRIPTION
Gathers Memory\Pages/Sec. statisticsGathers
.EXAMPLE
Get-Memory -Computername localhost | ConvertTo-Html | Out-File C:\
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$Computername )
Begin { $Info = Get-Date ; Hostname }
Process { $Memory = Get-Counter -Counter "\Memory\Pages/sec" -SampleInterval 1 -MaxSamples 3 |
Format-Table -AutoSize |
Out-String
$Cmd = wmic cpu get loadpercentage }
End { $Info, $Memory, $Cmd }
}
Function Get-Uptime {
<#
.CREATED BY:
Chris Davis
.MODIFIED BY:
Matthew A. Kerfoot
.MODIFIED ON:
10\30\2013
.Synopsis
Outputs how long since the last reboot
.DESCRIPTION
This function gathers information regarding when $ComputeName was last rebooted. `
.EXAMPLE
Get-Uptime localhost | ConvertTo-Html | Out-File C:\
Referance - http://pc-addicts.com/my-powershell-scripts/
#>
[CmdletBinding()]
param ( [Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string]$ComputerName = "$env:COMPUTERNAME" )
Begin { $OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computername
$diff = $OS.ConvertToDateTime($OS.LocalDateTime) - $OS.ConvertToDateTime($OS.LastBootUpTime) }
Process { foreach ( $_ in $ComputerName ){
@{ "ComputerName" = $Computername
"Days" = $diff.Days
"Hours" = $diff.Hours
"Minutes" = $diff.Minutes } } }
End { New-Object -TypeName PSObject -Property $properties | Format-Table -AutoSize }}
Function Write-HTML {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
11\3\2013
.SYNOPSIS
Creates an HTML file on the Desktop of the local machine full of detailed system information.
.DESCRIPTION
Write-HTML utilizes WMI to retrieve information related to the physical hardware of the machine(s), the available disk space, when the machine(s) last restarted and bundles all that information up into a colored HTML report.
.EXAMPLE
Write-HTML -Computername localhost, SRV-2012R2, DC-01, DC-02
This will create an HTML file on your desktop with information gathered from as many computers as you can access remotely
#>
[CmdletBinding(SupportsShouldProcess=$True)]
param([Parameter(Mandatory=$false,
ValueFromPipeline=$true)]
[string]$FilePath = "C:\users\$env:USERNAME\desktop\Write-HTML.html",
[string[]]$Computername = $env:COMPUTERNAME,
$Css = "<style> table{margin:auto; width:98%}
Body{background-color:Orange; Text-align:Center;}
th{background-color:black; color:white;}
td{background-color:Grey; color:Black; Text-align:Center;}
</style>" )
Begin{ Write-Verbose "HTML report will be saved $FilePath" }
Process{ $Hardware = Get-WmiObject -class Win32_ComputerSystem -ComputerName $Computername |
Select-Object Name,Domain,Manufacturer,Model,NumberOfLogicalProcessors,
@{ Name = "Installed Memory (GB)" ; Expression = { "{0:N0}" -f( $_.TotalPhysicalMemory / 1gb ) } }|
ConvertTo-Html -Fragment -As Table -PreContent "<h2>Hardware</h2>" |
Out-String
$PercentFree = Get-WmiObject Win32_LogicalDisk -ComputerName $Computername |
Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,VolumeName,DeviceID,
@{ Name = "Size (GB)" ; Expression = { "{0:N1}" -f( $_.Size / 1gb) } },
@{ Name = "Free Space (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
@{ Name = "Percent Free" ; Expression = { "{0:P0}" -f( $_.FreeSpace / $_.Size ) } } |
ConvertTo-Html -Fragment -As Table -PreContent "<h2>Available Disk Space</h2>" |
Out-String
$Restarted = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computername |
Select-Object Caption,CSName,
@{ Name = "Last Restarted On" ; Expression = { $_.Converttodatetime( $_.LastBootUpTime ) } }|
ConvertTo-Html -Fragment -As Table -PreContent "<h2>Last Boot Up Time</h2>" |
Out-String
$Stopped = Get-WmiObject -Class Win32_Service -ComputerName $Computername |
Where-Object { ($_.StartMode -eq "Auto") -and ($_.State -eq "Stopped") } |
Select-Object SystemName, DisplayName, Name, StartMode, State, Description |
ConvertTo-Html -Fragment -PreContent "<h2>Services currently stopped that are set to autostart</h2>"|
Out-String
$Report = ConvertTo-Html -Title "$Computername" `
-Head "<h1>PowerShell Reporting<br><br>$Computername</h1><br>This report was ran: $(Get-Date)" `
-Body "$Hardware $PercentFree $Restarted $Services $Stopped $Css" }
End{ $Report | Out-File $Filepath ; Invoke-Expression $FilePath }
}
Function Get-Stopped {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
10\29\2013
.Synopsis
Finds Services set to start automatically but are stopped
.DESCRIPTION
This function will find all services that are set to start automatically at startup but are not currently running.
.EXAMPLE
Get-Stopped -ComputerName localhost | Out-file "$env:USERPROFILE\Desktop\StoppedServices.txt"
#>
[CmdletBinding()]
Param ( [Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$Computername )
Begin { $Obj = Get-WmiObject -Class Win32_Service }
Process { $Stopped = $Obj | Where-Object { ($_.StartMode -eq "Auto") -and ($_.State -eq "Stopped") } |
Select-Object Name, DisplayName, StartMode, State, Description }
End { $Stopped | Format-Table -AutoSize }
}
Function Get-FreeSpace {<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
10\21\2013
.Synopsis
Gathers Disk Drive Available FreeSpace Percentage
.DESCRIPTION
This function gathers information about HDDs and then reformats the output `
to an easy to read output with the available FreeSpace percentage.
.EXAMPLE
Get-FreeSpace localhost | ConvertTo-Html | Out-File C:\
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$Computername )
Begin { $Begin = Get-WmiObject Win32_LogicalDisk }
Process { $Process = $Begin | Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,
@{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
@{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
@{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
@{ Name = "PercentFree" ; Expression = {"{0:P2}" -f( $_.FreeSpace / $_.Size ) } } }
End { $Process | Format-Table -AutoSize }
}
Function Start-Cleanup {
<#
.CREATED BY:
Matthew A. Kerfoot
.CREATED ON:
10\17\2013
.Synopsis
Aautomate cleaning up a C: drive with low disk space
.DESCRIPTION
Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, `
the local users Temperary folder, IIS logs(if applicable) and empties the recycling bin. `
All deleted files will go into a log transcript in C:\Windows\Temp\. By default this `
script leaves files that are newer than 7 days old however this variable can be edited.
.EXAMPLE
PS C:\Users\mkerfoot\Desktop\Powershell> .\cleanup_log.ps1
Save the file to your desktop with a .PS1 extention and run the file from an elavated PowerShell prompt.
.NOTES
This script will typically clean up anywhere from 1GB up to 15GB of space from a C: drive.
.FUNCTIONALITY
PowerShell v3
#>
function global:Write-Verbose ( [string]$Message )
# check $VerbosePreference variable, and turns -Verbose on
{ if ( $VerbosePreference -ne 'SilentlyContinue' )
{ Write-Host " $Message" -ForegroundColor 'Yellow' } }
## Begin the timer.
$Starters = (Get-Date)
$VerbosePreference = "Continue"
$DaysToDelete = 7
$LogDate = get-date -format "MM-d-yy-HH"
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace(0xA)
$ErrorActionPreference = "silentlycontinue"
## Cleans all code off of the screen.
Clear-Host
Start-Transcript -Path C:\Windows\Temp\$LogDate.log
Write-Verbose "retriving current Disk percent free for comparison once the script has completed."
$Before = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,
@{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
@{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
@{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
@{ Name = "PercentFree" ; Expression = {"{0:P1}" -f( $_.FreeSpace / $_.Size ) } } |
Format-Table -AutoSize | Out-String
## Stops the windows update service.
Get-Service -Name wuauserv | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue
## Windows Update Service has been stopped successfully!
## Deletes the contents of windows software distribution.
Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete)) } |
remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
Write-Verbose "The Contents of Windows SoftwareDistribution have been removed successfully!"
## Deletes the contents of the Windows Temp folder.
Get-ChildItem "C:\Windows\Temp\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete)) } |
remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
Write-Verbose "The Contents of Windows Temp have been removed successfully!"
## Delets all files and folders in user's Temp folder.
Get-ChildItem "C:\users\*\AppData\Local\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete))} |
remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
Write-Verbose "The contents of C:\users\$env:USERNAME\AppData\Local\Temp\ have been removed successfully!"
## Remove all files and folders in user's Temporary Internet Files.
Get-ChildItem "C:\users\*\AppData\Local\Microsoft\Windows\Temporary Internet Files\*" `
-Recurse -Force -Verbose -ErrorAction SilentlyContinue |
Where-Object {($_.CreationTime -le $(Get-Date).AddDays(-$DaysToDelete))} |
remove-item -force -recurse -ErrorAction SilentlyContinue
Write-Verbose "All Temporary Internet Files have been removed successfully!"
## Cleans IIS Logs if applicable.
Get-ChildItem "C:\inetpub\logs\LogFiles\*" -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { ($_.CreationTime -le $(Get-Date).AddDays(-60)) } |
Remove-Item -Force -Verbose -Recurse -ErrorAction SilentlyContinue
Write-Verbose "All IIS Logfiles over $DaysToDelete days old have been removed Successfully!"
Write-Verbose "deleting the contents of the recycling Bin."
$objFolder.items() | ForEach-Object { Remove-Item $_.path -ErrorAction Ignore -Force -Verbose -Recurse }
Write-Verbose "The Recycling Bin has been emptied!"
$After = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,
@{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
@{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
@{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
@{ Name = "PercentFree" ; Expression = {"{0:P1}" -f( $_.FreeSpace / $_.Size ) } } |
Format-Table -AutoSize | Out-String
Write-Verbose "looking for any large .ISO and or .VHD\.VHDX files."
$size = Get-ChildItem -Path C:\* -Include *.iso, *.vhd, *.vhdx -Recurse -ErrorAction SilentlyContinue
## Stop timer.
$Enders = (Get-Date)
## Calculate amount of seconds your code takes to complete.
Write-Verbose "Elapsed Time: $(($Enders - $Starters).totalseconds) seconds"
## Sends some before and after info for ticketing purposes
Hostname ; Get-Date | Select-Object DateTime
Write-Verbose "Before: $Before"
Write-Verbose "After: $After"
Write-Verbose ( Get-ChildItem -Path C:\* -Include *.iso, *.vhd, *.vhdx -Recurse -ErrorAction SilentlyContinue |
Sort Length -Descending | Select-Object Name, Directory,
@{Name="Size (GB)";Expression={ "{0:N2}" -f ($_.Length / 1GB) }} | Format-Table -AutoSize |
Out-String )
## Completed Successfully!
Stop-Transcript }
Function Get-Installed {
<#
.Synopsis
This function will retrieve information related to all installed programs.
.DESCRIPTION
This function checks you regestry for installed programs and then gives you a verbose output that is easy to read.
.EXAMPLE
Get-Installed
This will retrieve a nice unformatted verbose output of all installed programs.
.EXAMPLE
Get-Installed | Format-Table -Autosize
This will retrieve information related to all installed programs and output it as a tightly formated table.
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
This cmdlet is best if ran against the a local computer with POwerShell v2.0+ installed.
#>
[CmdletBinding()]
Param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
$VerbosePreference = "Continue",
$Color = "Green"
)
Begin{
$Host.PrivateData.VerboseForegroundColor = "$Color"
$HKLM = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
}
Process{
$Output = $HKLM | Select-Object DisplayName, DisplayVersion, Publisher,
@{ Name = "Installed On:" ; Expression = {[Datetime]::ParseExact($_.InstallDate,"yyyyMMdd",$null).ToShortDateString() } } | Out-String
}
End{
Write-Verbose "$env:COMPUTERNAME $Output"
}
}
Function Get-PSknowledge{
<#
.Synopsis
Gets a random cmdlet's help file examples
.DESCRIPTION
Gets a random cmdlet's help file examples
.EXAMPLE
PS C:\ > Get-Random
.EXAMPLE
PS C:\ > Get-Random
.NOTES
Gets a random cmdlet's help file examples
#>
[CmdletBinding()]
Param( [Parameter( ValueFromPipelineByPropertyName = $true )]
$VerbosePreference = "Continue" )
$Random = Get-Command | Get-Random | help -Examples | Out-String
Write-Verbose "$Random"
}
}
New-item -type file -force "$env:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
$NewPROFILE > "$env:USERPROFILE\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
Clear-Host
Start-Process powershell.exe -Verb RunAs
# SIG # Begin signature block
# MIID8AYJKoZIhvcNAQcCoIID4TCCA90CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUy4Bnx+BtNK7lNP25S0f2VjPy
# p8+gggIJMIICBTCCAW6gAwIBAgIQW3AY1oxn2IpMGvmz937aaDANBgkqhkiG9w0B
# AQUFADAdMRswGQYDVQQDDBJNYXR0aGV3IEEuIEtlcmZvb3QwHhcNMTQwMzMxMTMx
# OTAwWhcNMjAwMjAxMDAwMDAwWjAdMRswGQYDVQQDDBJNYXR0aGV3IEEuIEtlcmZv
# b3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKXMI45bjtKfTay1bILtitbh
# DSzfQpYBIYMUbyWZJEg5M7OU9vx8+UaByjKl3VHvV1tWY4XKWhblIynKWd9C+tQG
# 14jYIE+QhEiOCj4jd929CdwOLd5wRhMnI3oAHO07horAbuiKHh1oKPmPL/de+Aq2
# MAbc9AjDfb7PKQH7B/8NAgMBAAGjRjBEMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB0G
# A1UdDgQWBBRk5JbswoBXt/q20rfjzgrsY4a/ITAOBgNVHQ8BAf8EBAMCB4AwDQYJ
# KoZIhvcNAQEFBQADgYEAh6Rjx8ycFvRTVqRfsD8e9Ei4JcQyMtALYQ/Xh8HrOW2u
# GOTAsTWVATejCXRpYpCVIyR66utEb3d9m1VXhOSttqAhaE9qVGMq9wCObqhl5C9M
# MNamY35NH/Bh4iUMkxj+ZzCkYA8wezrW5KWVP7bVADzfj1AKLIoGnBgqS8+UX9wx
# ggFRMIIBTQIBATAxMB0xGzAZBgNVBAMMEk1hdHRoZXcgQS4gS2VyZm9vdAIQW3AY
# 1oxn2IpMGvmz937aaDAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAA
# oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w
# DAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUs+HlDr0zS2eqYLC5sFhCeBSu
# bxMwDQYJKoZIhvcNAQEBBQAEgYAlqKpw+DO+16NzC6DiZgRrms13GI7LVYm9xfIK
# oeOB/HuIsfXpRGi0dIJyGVSC28CFEiQaryEnOTuJVaFB/2aImBqb/NDosPHL9Orr
# FboF9zI/lgZbAZ6Uppyzi7k6rJcyqa+ivcnvgoF79AwC++MuTQNwEVDzSW+Thg7I
# Ebt8pw==
# SIG # End signature block
Click Here to download from the Microsoft Script Repository