Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the twentyseventeen domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /var/www/html/wp-includes/functions.php on line 6121
Install – Page 2 – SCCMOG – Deployment Blog

Set IP during Task Sequence PowerShell – SCCM ConfigMgr MDT

So this Is an older script of mine that I developed for a client to receive variables from a task sequence and then assign the IP of the machine based off the variables. This specfic client set the IP variables on the actual Machine object in SCCM so that during the task sequence it would pull the machine specific IP details. Their Task seqeunce was running only ConfigMgr tasks but this could quite easily be re-used for a ConfigMgr / MDT task sequence using the custom settings or database to set the IP Variables.

As always this is as is, the usage is defined in the script header and if you do use it please remember to use the modded by field 🙂

############################################################################
#Author   : Richie Schuster C5 - SCCMOG.com
#ModdedBy : Your Name here....
#Date     : 23/06/2017
#Script   : Set-MachineNetworkConfiguration.ps1
#Usage    : Set-MachineNetworkConfiguration.ps1 -IPAdress %IPAddress% -Subnet %SubMask% -Gateway %GateWay% 
#         : -DNS1 %DNS1% -DNS2 %DNS2%
#         : There is also a Switch -RevDNSAuto that allows for the DNS to be auto set on revert or not.
#Info     : This script has been created to auto configure Network information during OSD using OSD Variables
#         : or using strings.
############################################################################

param (
[string]$IPAddress,
[string]$Subnet,
[string]$Gateway,
[string]$DNS1,
[string]$DNS2,
[string]$PrimarySiteServer,
[switch]$RevDNSAuto
)

<##Testing Variables
[string]$IPAddress = "192.82.33.149"
[string]$Subnet = "255.255.255.0"
[string]$Gateway = "192.82.33.1"
[string]$DNS1 = "192.82.33.244"
[string]$DNS2 = "192.82.34.244"
[string]$PrimarySiteServer = "192.82.33.11"
[switch]$RevDNSAuto = $false

#Variables
$REVDNS1 = "192.82.1.22"
$REVDNS2 = "192.82.1.22"
#Create Task Sequence Variable Play!
$TSENV = New-Object -COMObject Microsoft.SMS.TSEnvironment

#Function to set IP Address - Credit "Petervanderwoude.nl"
function Set-StaticIPAddress ($IPAddress, $Subnet, $Gateway, $DNS1, $DNS2) {
    $NewNetworkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IpEnabled = 'True'"
    $NewNetworkConfig.EnableStatic($IPAddress, $Subnet)
    $NewNetworkConfig.SetGateways($Gateway, 1)
    $NewNetworkConfig.SetDNSServerSearchOrder(@($DNS1, $DNS2))
}

#Set new Configuration
Set-StaticIPAddress $IPAddress $Subnet $Gateway $DNS1 $DNS2
#Sleep to take wait effect
sleep -Seconds 10
#Test Connection
If (Test-Connection -ComputerName $PrimarySiteServer -Count 10) {
    #If connection succeded...
    Write-Host "Configuration Succeeded!" -ForegroundColor Green
    #Set Task seqeunce Variable to False
    $TSENV.Value("NetworkConfig") = "Static"
    #Exit 0
}
Else {
    #If connection failed...
    Write-Host "Configuration Failed! Setting back to DHCP!" -ForegroundColor Yellow
    #Set Task seqeunce Variable to False
    $TSENV.Value("NetworkConfig") = "DHCP"
    #Get current IP settings swap to DHCP
    $CurrentNetworkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'"
    #Set DNS Servers check switch
    If ($RevDNSAuto -ne $true) {
        #Set DNS to specified variable values
        $CurrentNetworkConfig.SetDNSServerSearchOrder(@($REVDNS1,$REVDNS2))
    }
    Else {
        #Set DNS to Auto
        $CurrentNetworkConfig.SetDNSServerSearchOrder()
    }
    #Enable DHCP
    $CurrentNetworkConfig.EnableDHCP()
    #Wait for configuration to complete
    Sleep -Seconds 10
    #Exit 0
}
######################################################################################

Scheduled Task Set ADR Disabled or Enabled SCCM ConfigMgr

When I setup a customers SCCM (ConfigMgr) site for patching I use ADR’s (Automatic Deployment Rules) to create a no hassle patching cycle each month.
This is done by automatically creating the monthly Software Update groups and then creating the deployments but NOT enabling them to the customer’s Pilot collections, Release Collections and Production Collections. This allows the customer to effectively “right click, enable” the deployment to that collection when ready.

The problem you have with this is the “Critical” security patches that are released out of the usual time period. You know the patches that cover that hole that no one noticed before release!
Anyway to get round that I create more ADR’s that run every day checking for a “Critical” Patch release. The issue with this is if left… Yep you guessed it, it will run on the monthly schedule day as well, which will just duplicate content.

So I came up with this Script to be run as a Scheduled Task by a service account just before the main ADR’s run and then later that day when they are complete.

Here is the Script:

##############################################################################################################################################
#Author: C5 Richie Schuster - SCCMOG.COM
#Script: Set-ADREnableDisabled
#Usage : "Set-ADREnableDisabled -State Enabled -SiteCode S0G" or "Set-ADREnableDisabled -State Disabled -SiteCode S0G"
#Info  : This script was writtent to run as a scheduled task to automatically disable and enable ADR Rules specified in the variable $ADRNames
##############################################################################################################################################
#Parameters
Param
(
[parameter(mandatory=$true,HelpMessage="Please, provide your SiteCode.")][ValidateNotNullOrEmpty()][String]$SiteCode = "",
[parameter(mandatory=$true,HelpMessage="Please, provide a state for the script to Run e.g. Enable or Disable")][ValidateNotNullOrEmpty()][String]$State = ""
)

#ADR Names stored in ARRAY -  Copy and Pasted name of ADR Bellow.
$ADRNames = @("ADR Critical Security Releases Windows 10 1607",`
            "ADR Critical Security Releases Windows 10 1511")

#Disable warnings for Fast switch
$CMPSSuppressFastNotUsedCheck = $true

# Check for elevation
Write-Host "Checking for elevation"
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator"))
{
    Write-Warning "Oupps, you need to run this script from an elevated PowerShell prompt!`nPlease start the PowerShell prompt as an Administrator and re-run the script."
    Write-Warning "Aborting script..."
    Break
}
#Import Module but check if user entered sitecode
If ($SiteCode -ne "") {
#[string]$SiteCode = "P01"
# Import the ConfigurationManager.psd1 module 
Write-Host "Importing ConfigMgr Module..." -ForegroundColor Yellow
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
# Set the current location to be the site code.
Write-Host "Setting Location to ConfigMgr Drive..." -ForegroundColor Yellow
Set-Location "$SiteCode`:"
}
Else {
    Write-Warning "Oupps, you need to enter a Site code!`nPlease use the -SiteCode followed by your sitecode."
    Write-Warning "Aborting script..."
    Break
}

#If State set to Disable
If ($State -eq "Disable") {
    Foreach ($ADR in $ADRNames) {
        #Retrieve ADR information
        $RetADR = Get-CMSoftwareUpdateAutoDeploymentRule -Name $ADR
            #Check if ADR is Enabled and if so disable
            If ($RetADR.AutoDeploymentEnabled -eq $True) {
                Write-Host "Its On... Disabling...." -ForegroundColor Yellow
                #Disable ADR
                Set-CMSoftwareUpdateAutoDeploymentRule -Name $RetADR.Name -Enable $false
                #Check Action successfully completed.
                $Check = Get-CMSoftwareUpdateAutoDeploymentRule -Name $ADR
                If ($Check.AutoDeploymentEnabled -eq $False) {
                    Write-Host "Successfully Disabled $($Check.Name)!" -ForegroundColor Green
                    }
            }
            #If ADR Already Enabled Warn User and move onto next.
            ElseIf ($RetADR.AutoDeploymentEnabled -eq $false) {
                    Write-Host "$($Check.Name) is already disabled!" -ForegroundColor Green
            }
            #If ADR same as previous name or not pupulated then warn user.
            Elseif (($RetADR.Name -ne $ADR) -or ($RetADR -eq $null)) {
                    Write-Host "ADR $ADR cannot be found!" -ForegroundColor Red        
            }
            #If you hit this something fishy is going on!
            Else {
                Write-Host "Error please message Richie Schuster C5 - SCCMOG.com" -ForegroundColor Red 
            }
    }
}

#If State set to Enable
ElseIf ($State -eq "Enable") {
    Foreach ($ADR in $ADRNames) {
        #Retrieve ADR information
        $RetADR = Get-CMSoftwareUpdateAutoDeploymentRule -Name $ADR
            #Check if ADR is Disabled and if so enable
            If ($RetADR.AutoDeploymentEnabled -eq $False) {
                Write-Host "Its Off... Enabling...." -ForegroundColor Yellow
                #Enable ADR
                Set-CMSoftwareUpdateAutoDeploymentRule -Name $RetADR.Name -Enable $True
                #Check Action successfully completed.
                $Check = Get-CMSoftwareUpdateAutoDeploymentRule -Name $ADR
                If ($Check.AutoDeploymentEnabled -eq $True) {
                    Write-Host "Successfully Enabled $($Check.Name)!" -ForegroundColor Green
                    }
            }
            #If ADR Already Disabled Warn User and move onto next.
            ElseIf ($RetADR.AutoDeploymentEnabled -eq $True) {
                    Write-Host "$($Check.Name) is already enabled!" -ForegroundColor Green
            }
            #If ADR same as previous name or not pupulated then warn user.
            Elseif (($RetADR.Name -ne $ADR) -or ($RetADR -eq $null)) {
                    Write-Host "ADR $ADR cannot be found!" -ForegroundColor Red        
            }
            #If you hit this something fishy is going on!
            Else {
                Write-Host "Error please message Richie Schuster C5 - SCCMOG.com" -ForegroundColor Red 
            }
    }
}
#If Input empty or does not match write warning.
Else {
    Write-Host "Please use Enable or Disable param e.g. Set-ADREnableDisabled -State Enable  -SiteCode S0G" -ForegroundColor Red
    Set-Location $PSScriptRoot
}
################################################################

Here is the XML for the Scheduled Task to disable the daily ADRs. You will have to change some details but this should get you going. When you want to re-enable it in the evening just change line 65 from Disable to enable:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2017-05-02T16:06:29.8383361</Date>
    <Author>SCCMOG\Administrator</Author>
    <Description>This task runs one a month to disable the critical security ADRs.</Description>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2017-05-02T01:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByMonthDayOfWeek>
        <Weeks>
          <Week>2</Week>
        </Weeks>
        <DaysOfWeek>
          <Wednesday />
        </DaysOfWeek>
        <Months>
          <January />
          <February />
          <March />
          <April />
          <May />
          <June />
          <July />
          <August />
          <September />
          <October />
          <November />
          <December />
        </Months>
      </ScheduleByMonthDayOfWeek>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>YourDomain\SCCMAdmin</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>Powershell.exe</Command>
      <Arguments>-ExecutionPolicy Bypass -File D:\Setup\Scripts\Set-ADREnableDisabled.ps1 .\Set-ADREnableDisabled.ps1 -State Disable -SiteCode P01</Arguments>
    </Exec>
  </Actions>
</Task>

Import IP Boundaries and Boundary Groups PowerShell SCCM ConfigMgr

This script is designed to work in harmony with the Export Sites and Subnets to CSV script I blogged about recently. The CSV file that is created by that script can then be used to import IP Subnet Boundaries and Groups with this PowerShell script.

Each Site will be Created as a Boundary Group and each Subnet listed with that Site in the CSV will be created as a IP Subnet Boundary associated to the Boundary Group.

Here is the Script:

#########################################################################################################
#Script Name:   Import Boundaries and Boundary Groups from CSV                                          #
#Script Author: SCCMOG - Richie Schuster 06/03/2017 WWW.SCCMOG.COM                                      #
#########################################################################################################
#Script Usage: ImportBoundariesandGroups.ps1 -CSVParam MyCSV.csv                                  #
#########################################################################################################

#CSV Name accepted as first PARAM
Param
(
[parameter(mandatory=$true,HelpMessage="Please, provide your SiteCode.")][ValidateNotNullOrEmpty()][String]$SiteCode,
[parameter(mandatory=$true,HelpMessage="Please, provide a CSV to import. It must be in the same folder as the script e.g. Sites.CSV")][ValidateNotNullOrEmpty()][String]$CSVParam
)

# Check for elevation
Write-Host "Checking for elevation"
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator"))
{
    Write-Warning "Oupps, you need to run this script from an elevated PowerShell prompt!`nPlease start the PowerShell prompt as an Administrator and re-run the script."
    Write-Warning "Aborting script..."
    Break
}

If ($CSVParam -ne ""){

    #Import CSV
    $path     = Split-Path -parent $MyInvocation.MyCommand.Definition 
    $newpath  = $path + "\$CSVParam"
    #Check location of CSV is valid.
    If (Test-Path $newpath){
    $BoundaryList = Import-Csv -Path $newpath
    #Import ConfigMgr Module
    Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
    #Set the current location to be the site code.
    Set-Location "$SiteCode`:"

        foreach ($_ in $BoundaryList){
            #Check If Boundary Group Already Created
            $getbg = Get-CMBoundaryGroup -Name $($_.Name)
 
            #If no bounday group maching that name create it
            if ($getbg -eq $null){
                New-CMBoundaryGroup -Description $($_.Name) -Name $($_.Name)
                }

            #Split on /
            $Subnet,$Bit = $_.Subnet.split('/',2)

            #Check if Boundary is already Created
            $getbn = Get-CMBoundary | where Value -eq $Subnet
    
            #If it is not then create new boundry and add it to Boundary Group
            if ($getbn -eq $null){
            New-CMBoundary -DisplayName $($_.Name) -BoundaryType IPSubnet -Value $Subnet
            Add-CMBoundaryToGroup -BoundaryGroupName $($_.Name) -BoundaryName $($_.Name)
                }
            }
        }
    Else{
    Write-Host "Please enter VALID CSV Name. Make sure it is in the same folder as this script." -ForegroundColor Cyan
    }
}
Else{
    Write-Host "Please enter CSV Name. Make sure it is in the same folder as this script." -ForegroundColor Cyan
}
###############################################################################################################

Below is a demonstration of the Script complete:

Import Boundaries and Groups PowerShell Script output
Import Boundaries and Groups PowerShell Script output
IP Subnet Boundaries Created
IP Subnet Boundaries Created
Boundary Groups Created
Boundary Groups Created
CSV from Export Script
CSV from Export Script

Export Sites and Subnets PowerShell to CSV

I came across an issue the other day when setting up a primary site for a customers Regional Office. The issue was that when enabling discovery methods namely the “Active Directory Forest Discovery“. As I’m sure you are aware there is a useful tick box that can be marked to “Automatically create IP address range boundaries for IP subnets when they are discovered“. This although a usually a useful check box caused the Discovery Method to pull back EVERY subnet listed globally… about 2500)!

So to get round this I created this PowerShell Script to export the Sites required and the Subnets associated with the sites in Active Directory Sites and Subnets. This script will export the data to a CSV that can then be imported into ConfigMgr later using this script.

Note: If you run the script without Parameters and just want to enter one Site to export, just hit enter on the next line and it will then ask you for save location.

Note: As in the image at the bottom of this page the save location must include the CSV Name e.g. “C:\temp\sites.csv”

#################################################################################################################################
#Script Name:   Export Specific Sites and Subnets to CSV                                                                        #
#Script Author: SCCMOG - Richie Schuster 06/03/2017 WWW.SCCMOG.COM                                                              #
#################################################################################################################################
#Script Usage: ExportSitesandSubnets -siteNames "Jersey" for single site , seperated "Jersey,Guernsey" -CSVOut C:\temp\site.csv #
#              for multiple.                                                                                                    #
#################################################################################################################################

#Params
Param
(
[parameter(mandatory=$true,HelpMessage="Please, provide Site Name(s). To list more than one site seprate with , e.g. Jersey,Guernsey ")][ValidateNotNullOrEmpty()][String[]]$siteNames,
[parameter(mandatory=$true,HelpMessage="Please, provide a location to save the Exported CSV with the filename. e.g C:\Temp\SCCMOGSites.CSV")][ValidateNotNullOrEmpty()][String]$CSVOut
)

 
#If entery is input run script
If ($siteNames -ne $null){

#Set Lists
[System.Collections.ArrayList]$sites = @()
[System.Collections.ArrayList]$sitesubnets = @()

#Get each site list in sitenames variable and add to variable
for ($i=0; $i -lt $siteNames.Count; $i++){
    $sites += [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites | Where-Object -Property Name -like $siteNames[$i]
    }

#Loop through each site and create simple match 
foreach ($site in $sites){
	foreach ($subnet in $site.subnets){
	   $temp = New-Object PSCustomObject -Property @{
	   'Name' = $site.Name
	   'Subnet' = $subnet; }
	    $sitesubnets += $temp
	}
}
#Export to CSV
$sitesubnets | Export-Csv $CSVOut -Force
}
#If params are not specified then inform.
Else{
    Write-host 'Script Param must be used : "ExportSitesandSubnets -siteNames Jersey" for single site or , seperated "Jersey,Guernsey" for multiple followed by -CSVOut C:\temp\site.csv' -ForegroundColor Yellow
    }
#########################################################################################################

The Image below shows the script being run and the output:

Export Sites and Subnets to CSV PowerShell Script
Export Sites and Subnets to CSV PowerShell Script

Copyright 2016 SCCMOG | All Rights Reserved