Wednesday, March 31, 2010

20100331 - slight update. Converting the hex items to dec and allowing passing of multiple drives.
20131230 - slight update. Changed the convert to use an Int64 instead of int32 as I was getting overflow on larger drives

A new function for my library. Base idea copped from Jacques Barathon [MS] at the bottom of this thread and hashed out to get all the properties.

Monday, March 29, 2010

Everybody has needed the 'delete files older than X' script. One more thing that is easier in powershell. In this case I have $env:temp/myfiles as my directory containing the files. I could also add -recurse to get-childitem if I wanted to get subdirectories as well. Anonymous noted below that you can add a test to exclude directories if you just want to clean the files out of the directory structure. I am using addminutes to delete files older than now - 15 minutes but you have other options. More on that here.

Note that if we want to delete all files older than X we would use -lt. ie, the timestamp of the file is older than 15 minutes ago. If we want to delete files newer than X we would use -gt. ie, the timestamp of the file is newer than 15 minutes ago. X, in our case, is the time now minus 15 minutes.

We are going to 'at' it. Although the Vista and later scheduling engine is vastly improved and renamed to schtasks.

Friday, March 26, 2010

Update: 201006018 – changed the reboot portion of the script to watch uptime instead of ping, some of my servers weren’t coming down fast enough. B)

For our last patch cycle we used Harry Johnston's vbs script to manage our updates. His script is here. (His very basic home page is here. I found the script from a newsgroup post or I would ping back or similar. Thanks Harry if you see this.)

If you want to do this completely with powershell, James O’Neill has posted is a pretty definitive discussion, Managing Windows Update with PowerShell. I don’t have powershell on all of my servers and don’t want to make that a requirement for this solution. As such, we are doing the actual work w/ the already present cscript engine and just managing the process w/ powershell.

Harry’s very useful script works whether you are pointing to windows updates or your own WSUS server. It checks for new updates, downloads, installs and reports whether you need a reboot. If you don't need a reboot, it runs itself again until it either needs a reboot or finds no patches. Cool script. we modified it slightly to spit out the hostname we were working w/ as we psexec'd it to run on a bunch of computers.

When we did this at first, we ran a few loops. First we copied the winupdates.vbs script to the c:\ on each computer to be updated. We would have run it from the fileshare but we wanted to have a single solution for our servers. Win2k8 servers run into a UAC problem w/ psexec. there may be a better way but we decided to pass -s to psexec to run as system (thus avoiding the UAC issues). Because we need to run as system, we cannot call the script from a network location (more specifically, we didn’t want to manage opening a network location that could be read by all the machine accounts)

We then ran a loop to pop out a command window for each server and run the script through sysinternal's psexec. When the script finished, it would report if it needed a boot. We would boot and then run the script again until the script had nothing to do.

This was much easier than getting on the servers and doing it but meh, it was still too much work.

The below powershell script will automate the copying the script and then loop the running, booting, waiting until there are no more patches to install. I did put in a 10 boot limit and a 15 minute limit waiting for reboots.

Save the script below as PSPatch.ps1. you will need to update the path to your winupdates.vbs and psexec at the top. To run it, just pass it a server name. ./pspatch.ps1 servertopath

Let me know if you use it...

#patch server

param (

$server

)

$scriptpath="c:\toolkit\scripts\winupdates.vbs"

$psexec="C:\Toolkit\sysint\psexec.exe"

if (-not (Test-Path$scriptpath)) { throw"Could not find Winupdates.vbs.Set location at top of script." }

if (-not (Test-Path$psexec)) { throw"Could not find psexec.Set location at top of script." }

Tuesday, March 23, 2010

I have often needed this and decided to finally sit down and write it. It basically, takes a set of reports and changes the data source to something else. In my case, I had a folder of reports that were pointing to one datasource and I wanted to point them all to another.