We don't auto-approve anything besides the Windows Defender updates. We do this using a custom Auto-Approve rule within WSUS like so:
So, updates are being approved, and now I would like to auto-decline superseded updates to keep things tidy. Why keep things tidy? I have a third-party patch management system that also let's me pull some pretty nifty reports on client patching progress, and if I don't remove these they sort of pollute my output by not being installed.
So I made a powershell script by adapting my old "Decline Itanium Patches" script.
Here's the script for declining superseded Definitions for Windows Defender updates:
$WsusServer = "WsusServer.contoso.com"
$UseSSL = $false
$PortNumber = 80
$TrialRun = $true
#E-mail Configuration
$SMTPServer = "SMTPServer.contoso.com"
$FromAddress = "administrator@contoso.com"
$Recipients = "me@contoso.com"
$MessageSubject = "PS Report - Declining Superceded Defender Updates"
Function SendEmailStatus($MessageSubject, $MessageBody)
{
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $Recipients, $MessageSubject, $MessageBody
$SMTPMessage.IsBodyHTML = $true
#Send the message via the local SMTP Server
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SMTPServer
$SMTPClient.Send($SMTPMessage)
$SMTPMessage.Dispose()
rv SMTPClient
rv SMTPMessage
}
#Connect to the WSUS 3.0 interface.
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
$WsusServerAdminProxy = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WsusServer,$UseSSL,$PortNumber);
$defender = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match "defender" -and $_.IsSuperseded -eq $true}
If ($TrialRun)
{$MessageSubject += " Trial Run"}
Else
{$defender | %{$_.Decline()}}
$Style = "<Style>BODY{font-size:11px;font-family:verdana,sans-serif;color:navy;font-weight:normal;}" + `
"TABLE{border-width:1px;cellpadding=10;border-style:solid;border-color:navy;border-collapse:collapse;}" + `
"TH{font-size:12px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}" + `
"TD{font-size:10px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}</Style>"
If ($defender.Count -gt 0)
{
$MessageBody = $defender | Select `
@{Name="Title";Expression={[string]$_.Title}},`
@{Name="KB Article";Expression={[string]::join(' | ',$_.KnowledgebaseArticles)}},`
@{Name="Classification";Expression={[string]$_.UpdateClassificationTitle}},`
@{Name="Product Title";Expression={[string]::join(' | ',$_.ProductTitles)}},`
@{Name="Product Family";Expression={[string]::join(' | ',$_.ProductFamilyTitles)}},`
@{Name="Uninstallation Supported";Expression={[string]$_.UninstallationBehavior.IsSupported}} | ConvertTo-HTML -head $Style
SendEmailStatus $MessageSubject $MessageBody
}
Running this script with $TrialRun set to $true (as it is initially) will simply email you what the script plans to do; it won't decline anything. Changing the $TrialRun variable to $false will actually decline things.
I set this script to run daily about an hour after my scheduled WSUS Synchronization.
In case you're wondering, the patch management system I'm running is Dameware Third Party Patching by Solarwinds. I'm still learning it and the curve is a bit steeper than I would like. At this time, I can't recommend it, but only because I need to learn more to use it effectively and not because it's a poor product (that I've found). I DO really like the reports it generates and I am successfully patching all Adobe Flash installs through my WSUS Server.
Click an Ad
If you find this blog helpful, please support me by clicking an ad!
Monday, June 10, 2013
Friday, June 7, 2013
Finding Files Over a Certain Length
So one thing that I've put into place following my Veeam restoration issue with long filenames is a script that runs daily on my fileservers that emails me when it finds any filename+filepath that's over 240 characters. The limit for an NTFS file is 256 characters, and a Veeam restore will choke if it tries to restore a file that exceeds this length.
Before I get into the script, I'd like to thank Ben for writing the actual action part of the script.
I have made modifications so that it runs where I want it to run and emails me if there are any results. Here it is:
#Let's find some long filenames
$files=Get-Childitem F:\ -Recurse
#Change Outpath to where you want log.
$Outpath = "C:\Temp\LongFiles.txt"
#MAIN SCRIPT
foreach ($file in $files)
{
if ($file.pspath.substring(38).length -gt 240)
{
if($File.Attributes -like "Directory*")
{
Write-Output ($File.PSPath.substring(38) + " is " + $File.Name.Length + " Characters Long, and it is a directory! The total path length is " + ($File.PSPath.Substring(38).length) + ".") >> $Outpath
} #End If
else
{
Write-Output ($File.PSPath.substring(38) + " is " + $File.Name.Length + " Characters Long, and it is a file! The total path length is " + ($File.PSPath.Substring(38).length) + ".") >> $Outpath
} #End Else
} #End If
} #End Foreach
#Email Parameters
$smtpserver = "mailserver.contoso.com"
$From = "administrator@contoso.com"
$To = "me@contoso.com"
$Subject = "PS Report - Long Filenames from <servername>"
$body = (Get-content $outpath | out-string)
#Sending the email
If ((Test-Path $outpath) -eq $True){
Send-Mailmessage -from $From -to $To -subject $Subject -smtpserver $smtpserver -body $body
} #End If
#Delete the log file
Remove-Item $outpath
So, a couple of things to mention about this:
I then set up a scheduled task to run the script every morning. The "Sending the email" portion tests to see if a logfile exists. If there is no logfile, then there are no files that meet the criteria (over 240 chars).
As is good practice, if there is nothing to say, the script does not email me. I have enough emails to dig through every day....
Before I get into the script, I'd like to thank Ben for writing the actual action part of the script.
I have made modifications so that it runs where I want it to run and emails me if there are any results. Here it is:
#Let's find some long filenames
$files=Get-Childitem F:\ -Recurse
#Change Outpath to where you want log.
$Outpath = "C:\Temp\LongFiles.txt"
#MAIN SCRIPT
foreach ($file in $files)
{
if ($file.pspath.substring(38).length -gt 240)
{
if($File.Attributes -like "Directory*")
{
Write-Output ($File.PSPath.substring(38) + " is " + $File.Name.Length + " Characters Long, and it is a directory! The total path length is " + ($File.PSPath.Substring(38).length) + ".") >> $Outpath
} #End If
else
{
Write-Output ($File.PSPath.substring(38) + " is " + $File.Name.Length + " Characters Long, and it is a file! The total path length is " + ($File.PSPath.Substring(38).length) + ".") >> $Outpath
} #End Else
} #End If
} #End Foreach
#Email Parameters
$smtpserver = "mailserver.contoso.com"
$From = "administrator@contoso.com"
$To = "me@contoso.com"
$Subject = "PS Report - Long Filenames from <servername>"
$body = (Get-content $outpath | out-string)
If ((Test-Path $outpath) -eq $True){
Send-Mailmessage -from $From -to $To -subject $Subject -smtpserver $smtpserver -body $body
} #End If
#Delete the log file
Remove-Item $outpath
So, a couple of things to mention about this:
- Change the get-childitem path to the one you wish to scour.
- Make sure you have a c:\temp path for the log file or change the output logfile's path.
- Change the email parameters.
- In the first 'If' statement, I changed his script to output anything over 240 characters in length, because that's all I really care about.
- Make sure you have access to the files or the script won't search those files/folders.
I then set up a scheduled task to run the script every morning. The "Sending the email" portion tests to see if a logfile exists. If there is no logfile, then there are no files that meet the criteria (over 240 chars).
As is good practice, if there is nothing to say, the script does not email me. I have enough emails to dig through every day....
Friday, May 31, 2013
Export Device Drivers from a Working System
A while ago I had to rebuild an old server on new hardware, and couldn't figure out what the fiber card that connected to our tape library was. This app helped me out big time. I still don't know, but I was able to export the driver using Double Driver and use it on the new system. It worked perfectly!
Wednesday, May 29, 2013
Understand the Script Before you Run it
Seasoned IT people have heard this a million times over: understand the script before you run it. This is a tale of woe and unforeseen overtime, that could have been avoided but for the mistakes of two intrepid IT pros. It's one of the best reasons to learn PowerShell, in my opinion. There are TONS of useful scripts out there to automate just about everything, and knowing just a bit can help you step through a script and to understand the concept of what a script is doing before you unleash it on, say, Active Directory.
We are in the process of breaking up a gigantic file server (2 TB) into 3 chunks. Having a file server this big is a big albatross. According to my math, restoring this puppy from backup would take around 36 hours. Longer-term, my plan is to pair the splitting with some sensible file storage policies and some kind of archiving for static files. Together, these should get the musketeers down to a more manageable size.
My cohort has volunteered to do the after hours work to move the file shares and reconfigure DFS. Being the helpful lad that I am, I gave him a command to make his life easier:
robocopy.exe <source> <target> /COPYALL /MIR
I am infatuated with robocopy. It's such a great little program. Copyall ensures that NTFS permissions and timestamps are preserved. MIR is the key part of this though; it ensures that the destination folder becomes an exact copy of the source. BUT MIR is a double-edged sword, and will delete files to achieve this end. I gave my cohort the command without explaining it. I really regret that, and it's illuminated that I need to do my part to ensure that people understand the tools that I'm giving them; this includes better documenting my code. I'm not horrible about it, but I could do better. There's always that line in the IT world where you have to assume that someone knows something, though, and it's tough to see where that is, sometimes. Telling him how to open the command prompt might seem condescending, right? Where do you start with someone? Misjudging that line is very easy to do, and can be very harmful.
But, I digress. So my partner runs the command, and moves some stuff one night. Last week, he discovered new stuff in the old "source" folder, so he ran the command again. See the problem? The MIR switch creates a mirror of the source, and about 50GB of files were no longer present in the source, so they were deleted. Ruh-Roh. I was just heading up to bed when my phone went off. He needed a file restore. A 54GB file restore. Of many small files. Not good. I fired up my trusty Veeam Backup & Replication and started restoring files. Wow was this thing moving slowly! I was getting throughput of 40KB/sec! A support call fixed that, but I want to tell you about some other really great things that I learned:
We are in the process of breaking up a gigantic file server (2 TB) into 3 chunks. Having a file server this big is a big albatross. According to my math, restoring this puppy from backup would take around 36 hours. Longer-term, my plan is to pair the splitting with some sensible file storage policies and some kind of archiving for static files. Together, these should get the musketeers down to a more manageable size.
My cohort has volunteered to do the after hours work to move the file shares and reconfigure DFS. Being the helpful lad that I am, I gave him a command to make his life easier:
robocopy.exe <source> <target> /COPYALL /MIR
I am infatuated with robocopy. It's such a great little program. Copyall ensures that NTFS permissions and timestamps are preserved. MIR is the key part of this though; it ensures that the destination folder becomes an exact copy of the source. BUT MIR is a double-edged sword, and will delete files to achieve this end. I gave my cohort the command without explaining it. I really regret that, and it's illuminated that I need to do my part to ensure that people understand the tools that I'm giving them; this includes better documenting my code. I'm not horrible about it, but I could do better. There's always that line in the IT world where you have to assume that someone knows something, though, and it's tough to see where that is, sometimes. Telling him how to open the command prompt might seem condescending, right? Where do you start with someone? Misjudging that line is very easy to do, and can be very harmful.
But, I digress. So my partner runs the command, and moves some stuff one night. Last week, he discovered new stuff in the old "source" folder, so he ran the command again. See the problem? The MIR switch creates a mirror of the source, and about 50GB of files were no longer present in the source, so they were deleted. Ruh-Roh. I was just heading up to bed when my phone went off. He needed a file restore. A 54GB file restore. Of many small files. Not good. I fired up my trusty Veeam Backup & Replication and started restoring files. Wow was this thing moving slowly! I was getting throughput of 40KB/sec! A support call fixed that, but I want to tell you about some other really great things that I learned:
- Veeam Enterprise paid for itself during this process. I was able to boot the VM as it was before the mishap, output a recursive directory listing (get-childitem) to a text file, and copy that file to my hard drive. Then, I did the same thing on the production side and used a program called Beyond Compare to compare the 2 text files to see where my file restore had gone wrong. This is the second time I've had to do something like this, and the hours of labor saved has more than paid for the higher-end version.
- Veeam (actually I think it's an NTFS issue) doesn't like files with a filename and path over 260 characters. How these files are allowed to exist on an NTFS filesystem in the first place, I have no idea, but it will stop a Veeam restore IN ITS TRACKS. Comparing the filesystems of yesterday vs today helped me see what had been restored and what I had yet to do.
- During my support call, it was imparted to me that using the Windows File Level Restore is not a good way to restore a lot of files at once (like 54GB worth of Word and Excel docs, for instance). Veeam takes a few seconds to verify each and every file, which is part of what was slowing me down. The tech showed me that after you mount the backup for the Windows FLR (so you're looking at the browser window) you should open regular old Windows Explorer and navigate to C:\VeeamFLR. Your drives will be mounted here, and you can use Explorer to copy and paste much more quickly.
So, lessons learned:
- Communicate more better
- Assume less
- Veeam Enterprise is gold, baby! (Beyond Compare is well worth the price as well)
- I need to find a way to comb my servers for really long paths+filenames
- Use the C:\VeeamFLR folder to copy from backups back to production; it's just easier.
Subscribe to:
Posts (Atom)