DHCP Failover and Recovery

,

I recently had an issue with a Domain Controller that was unresponsive at a remote site. Since it was just a virtual machine with no special settings, I punted and rebuilt the server. After I did all the recommended steps for removing a DC from Active Directory and was already configuring the new server, I remembered that I had setup DHCP Failover for this site. I would be lying if I did not say a twinge of panic set in at that moment. I had setup DHCP Failover in hot standby mode almost five years ago and had not not given it a second thought. Fortunately, the process was so simple that I did not even need to use PowerShell. I deleted the old Failover Relationship and then recreated it. The detailed steps are below.

Delete Old Failover Relationship

First on the active DHCP server, open DHCP Manager. Right click on IPv4 and choose Properties

On the Failover tab, select the failover relationship and click Delete.

Click OK to confirm the deletion.

The Failover Relationship is deleted. Note that you will see failure messages if the partner server cannot be reached. Click Close.

Create New Failover Relationship

Now that the old failover relationship is removed, we can recreate it. Obviously, you will need to repair or rebuild the DCHP failover partner server first. Once the partner server is ready, open the DHCP Manager on the active server. Right click on the scope and choose Configure Failover.

Select the Scopes and click Next.

Click Add Server.

Type the server name or select it from the list of authorized DHCP servers. Click OK.

Click Next.

Configure Failover Options for your environment. You may need to choose a new Relationship Name if the previous DHCP Failover was not successfully deleted. Click Next.

Confirm the settings and click Finish.

Once the DHCP Failover is created click Close.

DHCP Failover is easy to configure and easy to recover. I was surprised at how smoothly I was able to add and delete the partnerships using Windows Server 2016 and 2019. I repeated the process several times as I wrote this article. I would suggest creating a DHCP failover partner especially if you have a remote site with little or no IT support staff. I was fortunate that I had setup DHCP Failover at this site several years ago. Of course, in my case better monitoring software would have helped alert me to the server failure sooner. Hopefully, I will be writing about installing and configuring monitoring software soon.

You may need to rely on PowerShell to remove a Failover Relationship. The commend Remove–DhcpServerv4Failover will delete the specified partnership. A complete list of PowerShell commands can be found here:

https://blogs.technet.microsoft.com/teamdhcp/2012/12/18/dhcp-failover-using-powershell/

 

Ben Dumke

@BenDumke

Finding Empty Device Collections in SCCM

, , , , , , , ,

Today’s script is going to be almost a one-liner, but a very useful one.  I had found SQL queries that would do this same thing, but I frequently find myself working on a computer that does not have the SQL management software installed on it, and this query doesn’t run cleanly through the SCCM Management software.  However, I’m always on a computer with PowerShell and since this runs through WMI, you don’t even need to connect to the SCCM site code drive.
Having the right amount of device collections in SCCM is a bit of a balancing act. You don’t want so few collections that you don’t have a good way to sort out your clients logically, but you don’t want so many that you’ve gunked up your database with entries you’re never actually going to use. On top of that, some of the companies I’ve contracted with have had many collections that never held a single client. This script will go through and find those empty collections for you.   If you just want the PS1 file, click HERE.

Step 1: Initializing a few variables
Typically, if I’m working with SCCM through WMI, I like to setup a few variables in my shell right away to make my life easier and save some keystrokes throughout the day.
$siteServer = “PriServer1″ # whatever the name of your primary server is
$namespace = “root/SMS/site_TST” # root/SMS/site_  whatever your site code is

If you’re constantly making WMI calls to SCCM, being able to just enter those variables instead of typing it all out can make things easier. At least, that’s what I’ve found.

Step 2: Get your SCCM Device Collections
This script is going to be done on a single line, but I’ll break it out into chunks first. The first thing we need to do is pull all of the device collections from SCCM.
Get-WmiObject -Namespace $namespace -ComputerName $siteServer -Class SMS_Collection -filter ‘CollectionType =2’
 
If you wanted to pull user collections, you would change ‘CollectionType = 2’ to ‘CollectionType = 1’
If you want to get both sets of collections, just leave out the -filter portion entirely.

Step 3: Check Those Collections for Members
There are a couple ways you could do this. You could pipe your collections to a ForEach loop with an if statement in it. Alternatively, I choose to just pipe the first cmdlet into a where statement that does it for me.
| where {$colID = $_.CollectionID;(Get-WmiObject -Namespace $namespace -ComputerName $siteServer -class SMS_FullCollectionMembership -filter “CollectionID=’$colID'”).count -eq 0}

What this is doing is setting a variable called “$colID” to be the collection ID number from the collection passed through the pipe.  Then, we’re going to do a WMI query to the SMS_FullCollectionMembership class, which is a class that maintains a list of every device/user to collection association. We’re adding a filter to only show collection IDs that match the one we want, counting up all the members, and if that number equals 0, we know the collection has nothing in it.

Step 4: Profit
If you just stop there, you have a set of list-formatted data that, while not pretty, does contain all the information and objects you need to do work. It’s not the easiest thing to read, but it does give you a very solid information dump about the empty collection that looks something like this:

device collections

 

Chances are, if you’re generating this report for a manager, customer, etc, they’re going to want it formatted a bit nicer, and they’ll probably want it in an Excel spreadsheet.  The easiest way to do this is:
| select Name,CollectionID | export-csv C:usersMyUserDocumentsEmptyCollections.csv -noTypeInformation

 Alternatively, if you get the go-ahead to remove these device collections, instead of piping to a select/export-csv statement, you can pipe to remove-wmiobject instead.
For the love of god, run it with -whatif first.  

Thanks for reading, and if you have any questions, feel free to post them in the comments. 

Using Custom Objects for Fun and Profit

, , , , ,

Custom objects were one of those things I never really saw the point of when I read about them. It wasn’t until I actually messed around with them that I really understood their uses. Custom objects are especially good for generating reports that pull data from multiple sources.  For example, let’s say your manager has requested a report of all the computers in your Accounting department. He wants to know their hostname, their IP Address, their Make/Model, and their Serial Number.  Now, there’s no built in function or class (that I know of) that will return all of those pieces of information, so we’ll have to pull from multiple data sets.  For this example, we’re going to need Active Directory, the Win32_BIOS class, and the Win32_ComputerSystem class. For the sake of argument, let’s say we’ll also need the Get-CompOU script from the previous post and the hostname of a computer in the Accounting department’s OU to get started.
An example asset report script can be downloaded here:
https://goo.gl/5bB03A

Step 1: Generate a list of all the computers needed for this report
$allComps = Get-ADComputer -SearchBase (Get-CompOU AccountingPC1) -filter * -properties * 

This gives us an array of all the computer objects hosted in the same OU as the Accounting PC we started with. We can get the hostname and IP information just from these objects, but we need more.

Step 2: Enumerate all the computer objects and start data mining
ForEach ($comp in $allComps)
{
        $SWMI = Get-WmiObject -ComputerName $comp.Name -class Win32_ComputerSystem
$BWMI = Get-WmiObject -ComputerName $comp.name -class Win32_BIOS

We’re not quite done with the loop yet, but this shows how we’re invoking the WMI classes needed for each computer.  Step 3 takes place within the same loop.

Step 3: Create the custom object to hold our required data
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name “Hostname” -Value $comp.Name
$object | Add-Member -MemberType NoteProperty -Name “DNSName” -Value $comp.DNSHostName
$object | Add-Member -MemberType NoteProperty -Name “Serial” -Value $BWMI.SerialNumber
$object | Add-Member -MemberType NoteProperty -Name “IPAddress” -Value $comp.IPV4Address 
 
$object | Add-Member -MemberType NoteProperty -Name “Make” -Value $SWMI.Manufacturer
$object | Add-Member -MemberType NoteProperty -Name “Model” -Value $SWMI.Model 

$allObj += $object
 }
 This one is pretty straight forward. It’s a lot of text just to say that you’re adding properties to an item you created, assigning those properties values based on multiple classes created in Step 2, and then adding that object to an array of objects.  You can type $allObj = @() at the beginning of your script, but it isn’t required.

Step 4: Profit
At this point, we can dump our report out to a CSV, or we can just output to the screen.  Typing $allObj will just output to the screen, but if we want to make a report our management will be proud of:
$allObj | export-csv -path C:usersAdminDocumentsAssetReport.csv -NoTypeInformation

And we’re done!  Now, if you’re working in an environment with SCCM or other management software, these reports might be more easily generated by querying that database. However, this will give you up to the minute accuracy as the WMI queries are done live.  If there’s anything you want to see, leave me a comment, and I’ll add that to my next post.

ALSO CHECK : A quick (and useful) PowerShell script