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
Powershell – 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
}
######################################################################################

PowerShell Add Variables to Machines from CSV SCCM ConfigMgr

So it used to be a bit trickier to add a customĀ variable or multiple variables to a machine object in SCCM/ConfigMgr. But since the addition of the awesome New-CMDeviceVariable Cmdlet it’s a breeze!

Basically I’m in the midst of automating a clients Server Builds. As they have a lovely spreadsheet with all details of each server I thought I’d nock this up as a starter this evening.

So the script imports the CSV specified andĀ from there creates the variables supplied in the CSVĀ to the machine that is named in the CSV (that’s a lot of CSV). If the script cant find the Machine objectĀ (say you are doing hundreds or thousands!) that is named in the CSV file it will log that name to a text file called “NotFound.txt” in the script root folder.

As always comments throughout the script explain every step.

Anyway here is the script and CSV example:

#########################################################################################################
#Script Author: SCCMOG - Richie Schuster 24/05/2017 WWW.SCCMOG.COM                                      #
#Modded By:     Your Name Here                                                                          #
#Script Name:   Add Variables to Machines from CSV                                                      #
#########################################################################################################
#Script Usage: Add-VariablesMachines.ps1 -SiteCode S0G -CSVParam MyCSV.csv                              #
#########################################################################################################

#Script Parameters
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. YourCSV.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 "Please run from elevated PowerShell prompt!"
    Write-Warning "Aborting script..."
    Break
}

#Double check CSV param
If ($CSVParam -ne ""){

    #Create path to CSV (back compat PS 2.0)
    $path     = Split-Path -parent $MyInvocation.MyCommand.Definition 
    $newpath  = $path + "\$CSVParam"
    #Check location of CSV is valid.
    If (Test-Path $newpath){
        $MachineCSV = 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`:"
            #Loop through each machine in CSV
            foreach ($Machine in $MachineCSV){
                #Check If Machine exists
                $Exists = Get-CMDevice -Name $($Machine.Name)
                #If no machine found log to txt file and report
                if ($Exists -eq $null){
                    Write-Warning "$($Machine.Name) not Found Logged to Notfound.txt"
                    Add-Content "$path\NotFound.txt" "$($Machine.Name)" -Force
                    }
                #If machine is found Create the Variables
                Else {
                    New-CMDeviceVariable -DeviceName $($Machine.Name) -VariableName "IPAddress" -VariableValue $($Machine.IPAddress) -IsMask 0
                    New-CMDeviceVariable -DeviceName $($Machine.Name) -VariableName "SubMask" -VariableValue $($Machine.SubMask) -IsMask 0
                    New-CMDeviceVariable -DeviceName $($Machine.Name) -VariableName "Gateway" -VariableValue $($Machine.Gateway) -IsMask 0
                    New-CMDeviceVariable -DeviceName $($Machine.Name) -VariableName "DNS1" -VariableValue $($Machine.DNS1) -IsMask 0
                    New-CMDeviceVariable -DeviceName $($Machine.Name) -VariableName "DNS2" -VariableValue $($Machine.DNS2) -IsMask 0
                }
            }
        #Set location back to script root
        Set-Location $path
        }
    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
}
###############################################################################################################

CSV:

Name,IPAddress,SubMask,GateWay,DNS1,DNS2
Proliant,192.168.1.88,255.255.255.0,192.168.8.254,192.168.1.1,192.168.1.2
SCCMOG-CM-01,192.168.1.90,255.255.255.0,192.168.8.254,192.168.1.1,192.168.1.2
NotHere,192.168.1.89,255.255.255.0,192.168.8.254,192.168.1.1,192.168.1.2
NotHere2,192.168.1.89,255.255.255.0,192.168.8.254,192.168.1.1,192.168.1.2
NotHere3,192.168.1.89,255.255.255.0,192.168.8.254,192.168.1.1,192.168.1.2

PowerShell Export Collection Members to CSV SCCM ConfigMgr

I was at a client’s yesterday and wanted to “True Up” SCCM/ConfigMgr’s Collection memberships compared to a spread sheet they had of their servers. Now I’m not an Excel wizard by any stretch of the Imagination! So the client said “Can you get me a CSV with the server names listed”.

The next thing that happened is bellow! It’s really quite a simple script when you think about it. As always comments throughout the script explain what is happening.

Anyway here it is:

#################################################################################################################
#Author:   Richie Schuster - SCCMOG.COM                                                                         #
#ModdedBy: You Name Here                                                                                        #
#Script:   Export-CMCollectionMembers                                                                           #
#Date:     23/05/2017                                                                                           #
#Usage:    Export-CMCollectionMembers -CollectionIDs S0G000F4,S0G000F2 -SiteCode S0G -CSVout C:\Temp\YourCSV.CSV#
#Update:   26/06/2017 - Removed Quotes from output.                                                             #
#################################################################################################################
#Input Parameters for Script
param (
[parameter(mandatory=$true,HelpMessage="Please, provide Collection ID(s). To list more than one Collection ID seprate with , e.g. S0G000F4,S0G000F2")][ValidateNotNullOrEmpty()][String[]]$CollectionIDS,
[parameter(mandatory=$true,HelpMessage="Please, provide a SCCM SiteCode. e.g S0G")][ValidateNotNullOrEmpty()][String]$SiteCode,
[parameter(mandatory=$true,HelpMessage="Please, provide a location to save the Exported CSV with the filename. e.g C:\Temp\YourCSV.CSV")][ValidateNotNullOrEmpty()][String]$CSVOut
)

#Set delimiter for CSV
$delimiter = ','

#Import the ConfigurationManager.psd1 module 
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
# Set the current location to be the site code. 
Set-Location "$SiteCode`:"

#Loop through Collection Members and add to Variable
Foreach ($Collection in $CollectionIDS) {
$MembersSep = Get-CMCollectionMember -CollectionId $Collection | Select-Object Name
$Members += $MembersSep
}

#Export to CSV specified removing quotes.
$Members | ConvertTo-Csv -Delimiter $delimiter -NoTypeInformation | foreach { $_ -replace '^"','' -replace "`"$delimiter`"",$delimiter -replace '"$','' } | out-file $CSVOut -fo -en ascii
#Set Location Back to Script Root
Set-Location -Path $PSScriptRoot

#################################################################################################################

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>

Copyright 2016 SCCMOG | All Rights Reserved