Powershell 2.0 Script to Create Server 2003 DHCP Scopes

I need to create roughly 200 DHCP scopes on a server in a backup location.

I"m running a Windows 2003 Mixed-Mode domain and only have access to Powershell 2.0 on those servers.

Action Plan:
With Powershell, can I export the scopes I need to re-create to a flat file, make the changes for the DNS and WINS settings, and then run a new script that creates the scopes from the flat file?

I found the following module to import but I don't understand how to use the functions to achieve what I'm after. Here's the link to the script. http://gallery.technet.microsoft.com/scriptcenter/05b1d766-25a6-45cd-a0f1-8741ff6c04ec
Who is Participating?
Chris DentConnect With a Mentor PowerShell DeveloperCommented:
heh this is quite a hard post to write, I have no wish to cause offence and text is a very poor medium for conveying that.

The long and short of it is I'm afraid I won't be able to help further. I just can't commit the time for something that extensive. Sorry.

I'd take a guess that it would take 1 to 2 days (dedicated) for me to write the script you need (as a one-off, including testing). The module you've found is a reasonable example of how complex this task is, looking at the creation and modification date in the description at the top only go to highlight this.

I urge you to explore what can be done by exporting / importing batches of scopes using the article posted above (it describes how to export individual or groups of named scopes). Then handle the modification using the CSV file and the script above. It's not a one-script-does-all solution, but I'm sure it can be made to work.

Sorry (again) that I cannot help further.

All the best.

Chris DentPowerShell DeveloperCommented:
> With Powershell, can I

No, not for DHCP. Or at least not without writing P/Invoke wrappers around the DHCP server API. That's been on my to-do list for a long time and isn't going anywhere fast.

The only available interface (pre-Windows 2012) is NetSh, which is precisely what that module you've found uses.

So, NetSh...

You can export a list of scopes like this:
netsh dhcp server \\ServerName show scope

Open in new window

If you're changing the DNS and WINS settings you need to pull the options from each scope.
netsh dhcp server \\ServerName scope ScopeAddress show optionvalue

Open in new window

The settings can be changed using a similar command:
netsh dhcp server \\ServerName scope ScopeAddress set optionvalue OptionCode

Open in new window

It quickly becomes clear we need to know the OptionCode values to proceed, those are 006 for DNS servers and 044 for WINS/NBNS Servers.

Obviously in it's current state that's going to be horrible to do, you need to chain all of those together to get do something reasonable.

Now we can use PowerShell.
# Assume this is being executed for a list of servers
$ServerList = "Server1", "Server2"
# We have two other options, we could pull the list of authorised DHCP servers from AD.
# And we could read that list from a file.

# Loop thorugh the list of servers
$ServerList | ForEach-Object {
  $Server = $_
  # Get the list of scopes from this server
  $Scopes = Invoke-Expression "netsh dhcp server \\$Server show scope"
  # Loop through the list of scopes to get the options
  $Scopes | Where-Object { $_ -match '^ (\d{1,3}\.\S+)' } | ForEach-Object {
    # Because of the regular expression match above, the reserved variable $matches now contains the Scope Address we need.
    $ScopeAddress = $matches[1]
    # Get the options set on this scope
    $Options = Invoke-Expression "netsh dhcp server \\$Server scope $ScopeAddress show optionvalue" | Out-String
    # Parse the DNS option value from the list of options. Close your eyes if you don't like regular expressions.
    if ($Options -match '\s+OptionId : 6\s*[\r\n]+((?!\s*OptionId)\s+.+[\r\n])+') {
      $DNSServers = $matches[0] -split '\n' |
        Where-Object { $_ -match '.+Value = (\S+)' } |
        ForEach-Object { $matches[1] }
    # Parse the WINS option value from the list of options. The same regular expression with a different, fixed, OptionId.
    if ($Options -match '\s+OptionId : 44\s*[\r\n]+((?!\s*OptionId)\s+.+[\r\n])+') {
      $WINSServers = $matches[0] -split '\n' |
        Where-Object { $_ -match '.+Value = (\S+)' } |
        ForEach-Object { $matches[1] }
    # Create a return value to allow these values to be exported.
    # DNSServers and WINSServers will be space-delimited within a single cell should you open the resulting CSV with Excel
    New-Object PsObject -Property @{
      Server      = $Server;
      Scope       = $ScopeAddress;
      DNSServers  = "$DNSServers";
      WINSServers = "$WINSServers";
} | Export-Csv ScopeReport.csv -NoTypeInformation

Open in new window

That's the report showing the current values. Importing those isn't so hard, or at least it isn't if we just assume things can be overwritten.
Import-Csv ScopeReport.csv | ForEach-Object {
  Invoke-Expression "netsh dhcp server \\$($_.Server) scope $($_.Scope) set optionvalue 006 $($_.DNSServers)"
  Invoke-Expression "netsh dhcp server \\$($_.Server) scope $($_.Scope) set optionvalue 044 $($_.WINSServers)"

Open in new window

It does nothing to validate success, but it is comparatively simple. Executing the first script again would, potentially, act as a verification step.

Finally, it all of these commands will run remotely. I've tested the first script, but not the second. And as I don't use WINS I've done nothing to verify they report properly.


Chris DentPowerShell DeveloperCommented:
And I should have paid a little more attention. More is required if we're to create the scopes as well.

I suggest you use this to export them and import them:


Then use the script I've written above to change the options if you need to.

Will that work for you?

Worried about phishing attacks?

90% of attacks start with a phish. It’s critical that IT admins and MSSPs have the right security in place to protect their end users from these phishing attacks. Check out our latest feature brief for tips and tricks to keep your employees off a hackers line!

LobsterguyAuthor Commented:
I'm needing to capture the values of the scope in its entirety. I would imagine a csv file the has the name of the scope, description, start IP, end IP, subnet mask, address range for distribution, exclusions for distribution, dns servers, wins servers, etc.

I need the ability to change the DNS entries. The read those entries in and create new scopes on a different server. I don't need to duplicate all of the entries from the source server but there are around 200 that will be duplicated. When I use Netsh to export the list I can't modify the file as it looks liked a garbled mess. I definitely don't want to import it without ripping out the scopes I don't need.
LobsterguyAuthor Commented:
I appreciate you taking the time to look at this and give me some feedback.
LobsterguyAuthor Commented:
Not sure how to assign points. While my question was answered it wasn't what I was looking for. But, since no one else has attempted I'll assign the points to close this question. I do appreciate you help Chris.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.