Week In Review : 07/20/2014

I had intended these to be weekly, and I got off track, sorry about that. So I missed the week of Jun 29, Jul 6 and Jul 13. I can tell you that the week of the 29th ended on July 5th, and I was pretty wiped out from all the fireworks and stuff. The week of the 6th we were in Florida on vacation and the last couple of weeks (Jul 13 and this week Jul 20) were about the same.

This week has been all about the code. My boss asked me to focus on getting the revised provisioning web app up and running, so I’m happy to report that it is on par with the previous version. The previous version was just a basic web app, nothing fancy, it had some pages that worked like a form and it was all driven by click events and such. It worked really well, but it lacked flexibility.

See, everything was written on a single page, the various “pages” were in reality Asp Panels separated by div’s. In order to add a feature I would have to figure out where to place it, then adjust all the code to handle it. Some of that was problem, I should have broken things out more earlier into separate functions, that may have made it easier, but I doubt it.

The new version is using MVC, each page has a model on the back to represent the data. So each page is strongly typed, For most things I use the built-in validation provided to me from that, for a few things I wrote some custom validation, for example to make sure someone chooses a valid option from a drop down and not the text “–Select an item–“. There are a few places where the custom validation just wasn’t appropriate. So I was able to create a couple of functions to handle that, I must say that in this new format it is a lot easier to work.

The way I have it now I just pass around the models from one page to the next, updating as we click along. I can pass those models to my custom validation and return a simple error message quite easily. Displaying the validation error’s previously was a pain, so I really enjoy the way this works.

Another nice feature is I can re-use a lot of what I do so I can provide new features. For example, I want to provide a way for admins to create a bare VM. I can use all the models I already have, as well as just about all the logic behind how that is wired up. If I want to add a new feature it’s as simple as writing up a model and then building a page for it, then writing a controller to handle it all, or updating an existing controller.

Some thoughts I’m having for the next version is to use the database, currently I’m not doing that at all, I’m actually querying VMware directly, this introduces some lag that the previous version didn’t have. I think that some of that can be resolved by me working through my code to get it optimized, but a lot of that is just inherent in how it all works.

So the thought was a separate job that would at regular intervals poll VMware for clusters, datastores, vm’s and so forth. Then the app becomes almost instantaneous, since instead of asking VMware we’ll ask the database. Then before we provision we will validate everything against VMware, which may introduce some entertaining issues, but as our change process is fairly slow I think this will work nicely.

The nice thing about storing this data I can add tables to give me logic that I had to code for before. I will be able to access some data without calling VMware since it will be stored in the database and some of the code I wrote to pull data from VMware I can dump as it won’t be needed.

So what all code am I using?

mod-VMware : allows users to connect to, query and clone (soon create) virtual machines
mod-proteus : allows users to connect to, query and add host records to Proteus and retrieve IP information for new hosts
mod-servicenow : allows users to connect to, query and create service tickets and configuration items
mod-Zenoss : allows users to connect to, query and add devices to Zenoss monitoring
mod-ads : allows users to connect to, query and create objects in Active Directory

I feel that I’m getting closer to my idea of being modular, where we can plug in the various things we want. I still haven’t worked that out yet, but in my head it works 😉


Week In Review : 06/01/2014

Another very productive week! Spent a lot of time on Operations Manager, and getting the Low-Privilege SQL Monitoring to work. There appears to be a problem with how the MP calculates PLE and is using data and advice that is now about 10yrs old, so I disabled that monitor.

We have about 20 SQL servers that are directly under our control, so trying to get those setup manually would have been painful. So I worked up a nice little SQL PowerShell module for automating some of that for me. Considering the number of servers in total we have, that code is really going to help out.

I didn’t spend all my time in Ops though, I did do a lot of Orchestrator this week. It’s been so nice having the network setup in such a way as to make this all so easy now. There are still some kinks that I need to work out, but otherwise it’s been really fun. One of things I did this week for Orchestrator was build a PowerShell module for it as well. I talked about that one Posted in IT, Orchestrator, Projects, Uncategorized, Windows PowerShell, WIR | Leave a reply

Week In Review : 05/25/2014

Well it’s been forever since I’ve written anything interesting so now is as good a time as any. Recently we were informed we needed to start keeping track of time spent on projects and since this is something I did for a couple of years at the School of Engineering, it’s not too difficult for me to get back into the swing. Although this go around I went with more of a journal style, not sure I like it but we’ll see.

LOTS of programming this week. I wrote a virtual machine provisioning app a while ago, and while functional I’m not sure how many folks actually use it. But there has been some renewed interest lately, mainly around removing a lot of the paperwork involved. So I’ve gotten to get my hands dirty playing around with various web services.

While not terribly fleshed out right now what I’ve got works for what we need.

  • I can communicate with VMware to provision a server
  • I can send the vlan information over to Proteus (Bluecat) to ask for the next available IP in the network
  • I can submit the details of the server, ram, cpu, disk, network information over to ServiceNOW for inventory
  • I can automatically generate tickets for handling backups and Zenoss monitoring
  • I can also talk direct to Zenoss to get the server into the system

I find more and more that programming is becoming more important for administering servers than perhaps it once was, or I’m just going off the deep-end with programming 😉

Here are the projects on GitHub associated with i’m working on now

You will note that I have a hyper-v module, but I’ve not talked about doing hyper-v at work. We actually have a little test cluster that we spun up earlier this month to start kicking the tires.

I’ve also been talking a lot with Microsoft. We’re working through an issue where provisioning users for Lync sometimes fails. It’s incredibly intermittent and next to impossible to reproduce. I’ve taken to having the guys turning on PowerShell logging (start-transcript) before they do anything just in case they catch it so we can pass that on to Microsoft.

Spent a few hours talking with one of their SQL support guys and now when an error occurs during provisioning, in addition to sending the error out to file; I also run a query that grabs data from one of the system tables regarding communication.

What else…System Center Advisor preview is AWESOME! I’ve been talking with a program manager at Microsoft as well as one or two guys who develop it about some feedback I had given and some issues I was having. Gotta say that’s been super fun, would so love to work there!

Oh! Finally got the monitoring VLAN all setup and started moving my servers into it. Had some fun issues there, first I couldn’t get to DNS so no name resolution, no accessing servers by names…fun times! Then, I forgot to file the change paperwork for changing the IP addresses of the servers, so the firewall rules never got updated…sigh

I’ve spent a fair amount of time getting Operations Manager all happy and cleaning up the various Management Pack issues that I’ve not dealt with since I’ve not been able to communicate with the servers. One of the more challenging parts for me lately has been getting the Low Privilege SQL monitoring working, I think I’ve got it all worked out now though so we’ll see how that goes next week.

In addition to being able to access the servers from the monitoring VLAN it also appears we have just about the same level of access from our desktops! No more RDP’ing into a dozen servers to do something like tweak a registry setting or stop a service!

Oh well, that’s it for this past week. I hope to start doing some more writing but I’ve decided to at least do these Week In Review posts.

Get recent events from servers

I’ve been working with Microsoft on an issue that I am having with my DPM server. We have been doing some fairly intense logging, and today I enable several performance counters in an attempt to ascertain if something external is triggering this issue.

Along those lines I thought it would be cool to get a list of log entries from two hours before the event occurs. The event I’m tracking is DPM 3101, Volume Missing. We have seen that during a regular backup something happens and then DPM stops with the message that the disk I’m backing up to is no longer connected.

I’ve started a thread and have participated in several other threads on the forums about this issue.

At any rate, I decided that I would write a script that would grab up all the events from my DPM server and my two file servers, that I’m backing up. The hope is that maybe something interesting will be logged.

Why the two hours? Well, it’s silly, but I’ve noticed that two hours seems to be significant in the timeline of how these things are happening.

The script is also available on the TechNet Gallery

Updated New-PrintJob script

The information I’m going to cover here was previously covered on TechNet. I’m posting this because this morning I came across an error in my PrintLogger script.To be fair it was an error in the script, there is something else going on. I have created a thread, but I don’t know if I’ll get much in the way of response, as the only hit on Google for the exact error message is a German site.

The jist of my problem is that when a job is submitted, I use Get-WinEvent to pull in all the events where the Event ID is 307. This is the job printed event and has all the details for the job that I’m interested in. On a busy server this can be a fairly large list, and while at the time of the error there were only about 2100 entries in the log, it was causing it to fail and not log anything.

The quick fix was to tack on –ErrorAction SilentlyContinue to the Get-WinEvent cmdlet. This allowed the code to continue through the error. Another fix would have been to limit the number of entries returned, but still not terribly accurate. Then I remembered that article I listed up at the top, and that I had been messing around with it.

The idea here is, when EventID 307 occurs to pass to the script the Record ID of the event that originally triggered the task. The original article talks about various ways of displaying this information, since I’m working in PowerShell I was more interested in the second.

The code to add is below, and you can add more entries based on the detailed view of a given event. I’ve not tried any others as all I need is the EventRecordID.


I followed the steps below, with the exception of not using the command-line to create and delete a task. I did this originally but later skipped that part as an import was much more simple.

  1. Create a task based event
  2. Right click the task and choose to export it
  3. Edit the XML file add the code above between the EventTrigger tags, and save
  4. Delete the original task
  5. Import the XML file and modify the properties for the action

For the start a program action, I will just refer you back to the article, all you need to remember is you will need to add two additional Parameters to your PowerShell script, $EventRecordID and $EventChannel.

$EventRecordID is the record number of the event that triggered this task

$EventChannel is the log where the event can be found

There was very little adjustment that needed to be done to the original script. I’ll test it for a day, but in limited testing the updated script produced identical results to the original.

This script is also available on the TechNet Gallery.

ExitCodes Part 2

So, yesterday I mentioned that I re-wrote the inventory script. Today I decided to re-write the reboot script. The idea behind the script is that once a week we bounce all the lab computers. We do this for various reasons, but since I’m in the mood decided today was the day to tackle that problem.

The last time I talked about this, I got a little off the beaten path hunting down all possible exit codes for the shutdown.exe command. While not wrapped around the axles this time, I did have to figure out how to deal with it.

The nice thing about PowerShell is that when running a command you have access to $LASTEXITCODE. This contains exactly what you think it contains, the number of the return code from the command-line program. Before I get to far ahead I do want to mention that when last I wrote about exit codes I found them on the Symantec site (still works). Today I found an archived newsgroup that had a link to the MSDN site, so I’ll put that here.

Ok, so I decided since I was re-writing this thing I wanted to be a little more accurate in my reporting of errors encountered. Now it was impossible for me to find what error codes are returned from shutdown.exe, most likely because it could be any number. So then I started looking at how I could get what it was using $LASTEXITCODE.

Buried deep in my brain I remembered that there was a net command that would give you a text version of the number.

net helpmsg 53

The network path was not found.

That seemed perfect, What happens if I use $LASTEXITCODE

net helpmsg $LASTEXITCODE

The operation completed successfully.

BRILLIANT! This was perfect, I decided to store the result in a variable and then write it out. The only problem, really more of a hassle, was that it returns a string array.

$result = (& net helpmsg $LASTEXITCODE)



After some poking around I realized that the first row is blank, the second row contains the message and that the remaining rows were empty. So in my case, one line padded top and bottom with empty rows. Then I began to wonder, are all the messages one-liners? So I wrote up a little routine to display all the messages, I’ll give you the final version of it.

$ExitCodes = (0..15818)
foreach ($ExitCode in $ExitCodes)
$ErrorActionPreference = 'SilentlyContinue'
(& net helpmsg $ExitCode)[1]

You might be asking why am I stopping at 15818? If you visited the link I gave you earlier you would have noticed that the codes ran higher than that. In fact the last page of that list is System Error Codes (12000-15999). Well if you scroll to the bottom of that page, you will note it stops at the above listed 15818. Now I don’t know why, but I figured why go any higher right? Well, I did and there isn’t anything there.

This script is pretty straightforward, it loops through each number and passes it to net helpmsg. All I did then was just ask for the second row [1] of that returned object. While I didn’t count all the returned messages, there were a lot, and for my situation, the one line on the second row was plenty for me.


The script can also be downloaded from TechNet.

PowerShell New-AdInventory script

I may have mentioned on here before that we rely quite heavily on Active Directory, and it’s true. It’s at the core of nearly all the services we deliver, the only exception would be the web, and that would really only be the public facing web sites.

I’ve also mentioned before that I’ve been moving over from VbScript to PowerShell, and I think it’s safe to say that I moved over quite a while ago. If you’ve not browsed my scripts you should head over to my code.google.com site to see what I’ve done.

Anyway, today I was working on a problem with a script that runs from a cron and after fixing that one, I realized I was still using my old inventory script to update Active Directory computer objects with some useful information. So I decided it was time that I rolled this script over to PowerShell. Now while I’d like to say the new and improved one is much more wicked awesome, it’s not, it’s just all PowerShell’d up.

The previous script I had created several functions to do things like send data to the event log. A rather generic function to return values from a remote computer via WMI. A nice little function to ping the computer, although looking back at the code I noticed that it’s not actually there, I should fix that.

At any rate the new script seems to go a little faster, and it certainly doesn’t look any shorter but most of that is actually documentation. Although technically since I dot-source in a library it’s significantly larger than the previous script.

This runs every hour and pulls the UserName, MacAddress, IPAddress and SerialNumber from the remote computer via WMI. I then write these values back to the computer object more or less using the same properties. Although description becomes UserName and ipHostNumber becomes IPAddress.

The nice thing is that we can then visually scan a given OU and see who might be logged into a computer. If there is an issue connecting to a computer, that is also written to the description property. That way as you browse your AD you can easily see which computers have problems, typically these are also dead computer accounts.

The code is also available on Technet.

Windows Server 8 Beta Failover Clustering and PowerShell

So the last two posts (one, two) were just some screenshots and comments as I went through and created a failover cluster. To be fair this wasn’t the first go round with the cluster I created one earlier with just one computer so I could see the PowerShell stuff.

I must say, 81 PowerShell commands to handle clustering, not too shabby. The first cluster I created was with the New-Cluster cmdlet.

New-Cluster -Name win8-hv -Node win8-hv1 -NoStorage -Verbose

The progress bar flashed for a bit as it did stuff and then there was a cluster. It didn’t take a long time but it was rather hot I must say.

Here are all the new commands

Get-Command |Where-Object {$_.ModuleName -eq 'FailoverClusters'} | Format-Table -Property Capability, Name -AutoSize

Capability Name
---------- ----
Cmdlet Add-VMToCluster
Cmdlet Remove-VMFromCluster
Cmdlet Add-ClusterCheckpoint
Cmdlet Add-ClusterDisk
Cmdlet Add-ClusterFileServerRole
Cmdlet Add-ClusterGenericApplicationRole
Cmdlet Add-ClusterGenericScriptRole
Cmdlet Add-ClusterGenericServiceRole
Cmdlet Add-ClusterGroup
Cmdlet Add-ClusteriSCSITargetServerRole
Cmdlet Add-ClusterNode
Cmdlet Add-ClusterPrintServerRole
Cmdlet Add-ClusterResource
Cmdlet Add-ClusterResourceDependency
Cmdlet Add-ClusterResourceType
Cmdlet Add-ClusterScaleOutFileServerRole
Cmdlet Add-ClusterServerRole
Cmdlet Add-ClusterSharedVolume
Cmdlet Add-ClusterVirtualMachineRole
Cmdlet Add-ClusterVMMonitoredItem
Cmdlet Block-ClusterAccess
Cmdlet Clear-ClusterDiskReservation
Cmdlet Clear-ClusterNode
Cmdlet Get-Cluster
Cmdlet Get-ClusterAccess
Cmdlet Get-ClusterAvailableDisk
Cmdlet Get-ClusterCheckpoint
Cmdlet Get-ClusterGroup
Cmdlet Get-ClusterLog
Cmdlet Get-ClusterNetwork
Cmdlet Get-ClusterNetworkInterface
Cmdlet Get-ClusterNode
Cmdlet Get-ClusterOwnerNode
Cmdlet Get-ClusterParameter
Cmdlet Get-ClusterQuorum
Cmdlet Get-ClusterResource
Cmdlet Get-ClusterResourceDependency
Cmdlet Get-ClusterResourceDependencyReport
Cmdlet Get-ClusterResourceType
Cmdlet Get-ClusterSharedVolume
Cmdlet Get-ClusterVMMonitoredItem
Cmdlet Grant-ClusterAccess
Cmdlet Move-ClusterGroup
Cmdlet Move-ClusterResource
Cmdlet Move-ClusterSharedVolume
Cmdlet Move-ClusterVirtualMachineRole
Cmdlet New-Cluster
Cmdlet Remove-Cluster
Cmdlet Remove-ClusterAccess
Cmdlet Remove-ClusterCheckpoint
Cmdlet Remove-ClusterGroup
Cmdlet Remove-ClusterNode
Cmdlet Remove-ClusterResource
Cmdlet Remove-ClusterResourceDependency
Cmdlet Remove-ClusterResourceType
Cmdlet Remove-ClusterSharedVolume
Cmdlet Remove-ClusterVMMonitoredItem
Cmdlet Repair-ClusterSharedVolume
Cmdlet Reset-ClusterVMMonitoredState
Cmdlet Resume-ClusterNode
Cmdlet Resume-ClusterResource
Cmdlet Set-ClusterLog
Cmdlet Set-ClusterOwnerNode
Cmdlet Set-ClusterParameter
Cmdlet Set-ClusterQuorum
Cmdlet Set-ClusterResourceDependency
Cmdlet Start-Cluster
Cmdlet Start-ClusterGroup
Cmdlet Start-ClusterNode
Cmdlet Start-ClusterResource
Cmdlet Stop-Cluster
Cmdlet Stop-ClusterGroup
Cmdlet Stop-ClusterNode
Cmdlet Stop-ClusterResource
Cmdlet Suspend-ClusterNode
Cmdlet Suspend-ClusterResource
Cmdlet Test-Cluster
Cmdlet Test-ClusterResourceFailure
Cmdlet Update-ClusterIPResource
Cmdlet Update-ClusterNetworkNameResource
Cmdlet Update-ClusterVirtualMachineConfiguration

So let’s play a little.

jeffpatton.admin@WIN8-HV1 | 12:56:01 | 03-20-2012 | C:Usersjeffpatton.admin #

Name OwnerNode State
---- --------- -----
Available Storage win8-hv2 Offline
broker win8-hv2 Online
Cluster Group win8-hv2 Online

jeffpatton.admin@WIN8-HV1 | 12:56:04 | 03-20-2012 | C:Usersjeffpatton.admin #
Remove-ClusterGroup -Name broker -RemoveResources

Are you sure that you want to remove the clustered role 'broker'? The resources will be taken offline.
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
jeffpatton.admin@WIN8-HV1 | 12:56:20 | 03-20-2012 | C:Usersjeffpatton.admin #
Remove-Cluster -Name win8-hv

Are you sure you want to completely remove the cluster win8-hv?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
jeffpatton.admin@WIN8-HV1 | 12:56:45 | 03-20-2012 | C:Usersjeffpatton.admin #
Get-Cluster : The cluster service is not running. Make sure that the service is running on all nodes in the cluster.
There are no more endpoints available from the endpoint mapper
At line:1 char:1
+ Get-Cluster
+ ~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Cluster], ClusterCmdletException
+ FullyQualifiedErrorId : Get-Cluster,Microsoft.FailoverClusters.PowerShell.GetClusterCommand

So I just dumped the cluster, I think I’ll create the cluster again with a single node, and then add a node after the fact, since there is a cmdlet for that.

New-Cluster -Name win8-cluster -Node win8-hv1 -NoStorage -Verbose


Let’s confirm that it’s there.

Get-Cluster |Format-List -Property *

Domain : soecs.ku.edu
Name : win8-cluster
AddEvictDelay : 60
BackupInProgress : 0
ClusSvcHangTimeout : 60
ClusSvcRegroupOpeningTimeout : 5
ClusSvcRegroupPruningTimeout : 5
ClusSvcRegroupStageTimeout : 5
ClusSvcRegroupTickInMilliseconds : 300
ClusterGroupWaitDelay : 120
MinimumNeverPreemptPriority : 3000
MinimumPreemptorPriority : 1
ClusterEnforcedAntiAffinity : 0
ClusterLogLevel : 3
ClusterLogSize : 300
CrossSubnetDelay : 1000
CrossSubnetThreshold : 5
DefaultNetworkRole : 2
Description :
FixQuorum : 0
HangRecoveryAction : 3
IgnorePersistentStateOnStartup : 0
LogResourceControls : 0
PlumbAllCrossSubnetRoutes : 0
PreventQuorum : 0
QuorumArbitrationTimeMax : 20
RequestReplyTimeout : 60
RootMemoryReserved : 4294967295
RouteHistoryLength : 0
SameSubnetDelay : 1000
SameSubnetThreshold : 5
SecurityLevel : 1
SharedVolumeCompatibleFilters : {}
SharedVolumeIncompatibleFilters : {}
SharedVolumesRoot : C:ClusterStorage
SharedVolumeSecurityDescriptor : {1, 0, 4, 128...}
ShutdownTimeoutInMinutes : 20
UseNetftForSharedVolumes : 1
UseClientAccessNetworksForSharedVolumes : 0
SharedVolumeBlockCacheSizeInMB : 0
WitnessDatabaseWriteTimeout : 300
WitnessRestartInterval : 15
EnableSharedVolumes : Enabled
DynamicQuorum : 1
Id : d4e05676-cf3d-4814-a828-f32e106bb1c0

Let’s see some information about the node.

Get-ClusterNode |Format-List *

Cluster : win8-cluster
State : Up
Id : 1
Name : win8-hv1
NodeName : win8-hv1
NodeHighestVersion : 467002
NodeLowestVersion : 467002
MajorVersion : 6
MinorVersion : 2
BuildNumber : 8250
CSDVersion :
NodeInstanceID : 00000000-0000-0000-0000-000000000001
Description :
DrainStatus : NotInitiated
DrainTarget : 4294967295
DynamicWeight : 1
NodeWeight : 1

Okay, let’s add a node now. I chopped off the crazy long report filename.

Add-ClusterNode -Name win8-hv2 -Cluster win8-cluster -NoStorage -Verbose
Report file location: C:WindowsclusterReportsAdd Node Wizard



Name ID State
---- -- -----
win8-hv1 1 Up
win8-hv2 2 Up

How many cluster do I have? Seems like a lot, but the Windows 8, and dev-cluster aren’t actually there anymore.

Get-Cluster -Domain soecs.ku.edu


Let’s add server role, this is basically a cluster end-point

Add-ClusterServerRole -Name Win8ServerRole -Cluster win8-cluster -Verbose

Name OwnerNode State
---- --------- -----
Win8ServerRole win8-hv1 Online

How about some details on that role. I cut out the Type property to keep it readable.

Get-ClusterResource -Name win8serverrole |Get-ClusterParameter

Object Name Value
------ ---- -----
win8serverrole Name WIN8SERVERROLE
win8serverrole DnsName Win8ServerRole
win8serverrole Aliases
win8serverrole RemapPipeNames 0
win8serverrole HostRecordTTL 1200
win8serverrole RegisterAllProvidersIP 0
win8serverrole PublishPTRRecords 0
win8serverrole ResourceData {1, 0, 0, 0...}
win8serverrole StatusNetBIOS 0
win8serverrole StatusDNS 0
win8serverrole StatusKerberos 0
win8serverrole CreatingDC \DC1.soecs.ku.edu
win8serverrole LastDNSUpdateTime 3/20/2012 6:17:30 PM
win8serverrole ObjectGUID e3fbfe6ba596a447a09fd4e117...

Preparing to upgrade DC’s to Windows Server 2008 R2

We decided it was time to move to R2 on the domain controllers, while we’re at it we also moved up to Windows 2008 Functional. Sadly we can’t go to 2008r2 functional until our last 2008 DC goes out of warranty, in 2014! Oh well, maybe something will happen to it…

Fairly straightforward process

  1. Transfer FSMO roles
  2. Take a VM snapshot
  3. Perform the DCPromo
  4. Uninstall ADDS binaries
  5. Export Logs
  6. Reset computer account
  7. Install Windows 2008R2 Core

Well this morning Boe Prox posted a nice function to poshcode, Get-FSMORoleOwner. This function returns what server owns which roles and it was very helpful as I performed my transfers. Originally I had wanted to use Powershell to perform my transfers, but without ADWS the built-in ActiveDirectory module wouldn’t load. So I performed the transfers the old-fashioned way, using the MMC. After each transfer I would run Get-FSMORoleOwner to verify that the role had been moved. This all went without a hitch as expected, then came the Domain Functional Level.

No big surprises here, we did a little digging and found that moving to 2008 Functional level was equivalent to staying at 2003. There are a few new features in 2008, the most interesting one for me at least, is the Interactive Logging. Raising the functional level was a breeze, and all domain controllers reported the same level within minutes.

Since I’ve been moving away from VBscript and over to PowerShell I decided to take my VM snapshot using the PowerShellCLI from VMware.

New-Snapshot -Name Pre-Demotion -VM dc1 -Description “Snapshot prior to demoting.”

In order to backup all the logfiles I threw together a quick little function Backup-EventLogs. It takes the name of the computer and uses Get-WinEvent to get all the logs available. It then writes out each log where the RecordCount is greater than 0 to a csv file, using Export-CSV. Carson pointed out that it may have been easier to copy the log files over…ya, well…dammit I wouldn’t have gotten a nifty function out of it though!

Anyway, resetting and re-installing are fairly vanilla, and I’m pretty sure I covered standing up a core server somewhere before.


Windows Server Core 2008 R2 File Server

In order to work around an issue we are currently experiencing with System Center Configuration Manager and Windows 2008 R2 Failover Clustering, we need to setup a file server. I decided to set this up as a Core server, and only install the File Services that we need. I won’t walk you through the setup options, just the steps to take once you’re into the console.

Rename the computer

netdom renamecomputer %computername% /newname:{newComputerName}

shutdown /r

Join the domain

netdom join ComputerName /domain:DomainName /userd:UserName /passwordd:*

shutdown /r

Install the required roles

dism /online /enable-feature /featurename:CoreFileServer

dism /online /enable-feature /featurename:NetFx2-ServerCore

dism /online /enable-feature /featurename:FSRM-Infrastructure-Core

Configure the firewall

Netsh advfirewall firewall set rule group=”File and Printer Sharing” new enable=yes

Netsh advfirewall firewall set rule group=”Remote Volume Management” new enable=yes

Netsh advfirewall firewall set rule group=”Remote Administration” new enable=yes

I don’t know if I need to explain a whole lot here, the first two things are fairly self-explanatory. Windows 2008 has a lovely computername after installation so you really want to rename it. Fortunately the %computername% works, so you don’t need to know what it is before you rename it. In order to join the domain you will need to reboot after the rename, if you don’t you will receive an error:

Failed to access network address

That newly renamed computer doesn’t actually exist yet, seems funny I know, but just do the reboot. You will also need to reboot after joining the domain. Thankfully though, that is the end of the reboots.

You will need to install the CoreFileServer role in order to actually create and share folders on the server. I enjoy using the File Server Resource Manager, in order for that to work you will need to install the next two features, NetFx2 and FSRM, FSRM requires .NET so they need to be done in that order.

Finally in order for clients to access your file shares, and for you to be able to manage them you will need to enable the rule groups listed above.