Trevor Sullivan's Tech Room

Minding the gap between administration and development

Posts Tagged ‘powershell’

PowerShell: Disable ConfigMgr Task Sequence Countdown Notification

Posted by Trevor Sullivan on 2011/11/22


If you are using Microsoft System Center Configuration Manager (SCCM / ConfigMgr) to deploy task sequences to ConfigMgr client systems, you may notice that by default, a countdown notification is shown as a balloon notification in the client’s system tray. In some cases, this functionality may be undesirable, and you may therefore wish to disable the balloon notification. Unfortunately, the task sequence properties GUI in the ConfigMgr console does not allow you to disable the notification, but you can do so via script.

The SMS_TaskSequencePackage class in the root\sms\site_lab (where “lab” is your three-digit ConfigMgr site code) WMI namespace represents each task sequence that has been created in a Configuration Manager hierarchy. The ProgramFlags property on this class contains a series of bitwise values (not sure if that’s the right term) which represent various options. In this case, we care about option 0x400 (1024 in base 10), which if enabled, disables the countdown timer.


PowerShell Code

The PowerShell code included below will allow you to specify a task sequence package ID that you would like to disable balloon notifications on. I suggest running the code inside of the PowerShell Integrated Scripting Editor (ISE).

Make sure you update your ConfigMgr server name (where the provider sits) and ConfigMgr site code before running it!

function Disable-ConfigMgrTaskSequenceNotification {
    param (
        [Parameter(Mandatory = $true)] $SccmServer
        , [Parameter(Mandatory = $true)] $SiteCode
        , [Parameter(Mandatory = $true)] $TaskSequenceID
    try {
        # Retrieve the WMI instance that represents the intended task sequence package
        $TaskSequencePackage = [wmi]"\\$SccmServer\root\sms\site_$SiteCode`:SMS_TaskSequencePackage.PackageID='$TaskSequenceID'";
    # If the WMI object does not exist, catch the error and deal with it ... somehow.
    catch [System.Management.Automation.RuntimeException] {
        Write-Host -Object ("A Windows Management Instrumentation error occurred.`n" + `
            "`n* Is the computer powered on?" + `
            "`n* Is a firewall blocking access to WMI?" + `
            "`n* Is the WMI service started on the remote system?");
    # If the object handle was acquired from WMI, then go ahead and process it
    if ($TaskSequencePackage) {

        # Echo out the current ProgramFlags value
        Write-Verbose -Message ("Current program flags for {0} are {1}" `
                    -f $TaskSequencePackage.Name, $TaskSequencePackage.ProgramFlags);

        # If the notification disablement is not enabled (confusing, I know), then enable it.
        if (($TaskSequencePackage.ProgramFlags -band 0x400) -eq 0) {
            Write-Verbose -Message ("Disabling countdown for task sequence: {0}" -f $TaskSequencePackage.Name);
            # This is where the meat is: perform the binary XOR operation (same as adding 1024 in base 10) and set
            # the resulting value back to the ProgramFlags property. Remember that -bxor oscillates between on & off, so
            # that's why we have to perform the check in the if { ... } statement, prior to blindly switching it.
            $TaskSequencePackage.ProgramFlags = $TaskSequencePackage.ProgramFlags -bxor 0x400;
            # Commit the in-memory WMI instance back to the ConfigMgr provider
    # If a task sequence cannot be found with the appropriate ID, then notify the user.
    else {
        Write-Host `
            -Object ("Could not find task sequence with ID {0} in the {1} WMI namespace on {2}" `
            -f $TaskSequenceID, "root\sms\site_$SiteCode", $SccmServer)

$SccmServer = '';
$SiteCode = 'LAB';
$TaskSequenceID = Read-Host -Prompt 'Please enter a task sequence ID to modify';

Disable-ConfigMgrTaskSequenceNotification `
    -SccmServer $SccmServer `
    -SiteCode $SiteCode `
    -TaskSequenceID $TaskSequenceID `

When you execute this script, you’ll be prompted for a task sequence ID, so make sure to have that handy.


Hope this helps!


Posted in configmgr, powershell, scripting, wmi | Tagged: , , , , , , , , , , , , , , | 1 Comment »

PowerShell / ConfigMgr: Count of Client Manufacturer / Models

Posted by Trevor Sullivan on 2011/11/09


If you’re an administrator of Microsoft System Center Configuration Manager (SCCM / ConfigMgr) 2007, you might be interested in finding out what make / model of client & server systems you have, and how many of each unique value you have. Most people would probably simply pull up a ConfigMgr report, but did you know that there’s an automated way to get this information as well?

Using PowerShell

You’ll need the following to execute this simple script:

  • A user account with access to the ConfigMgr provider
  • The hostname of the ConfigMgr central site server
  • The site code of the ConfigMgr central site

Once you’ve launched PowerShell under the appropriate account’s credentials, simply run this command:


$ComputerSystems = Get-WmiObject `
    -Namespace root\sms\site_000 `
    -ComputerName `
    -Class SMS_G_System_Computer_System

$ComputerSystems `
    | Group-Object -Property Manufacturer,Model `
    | Where-Object { $_.Count -gt 5 } `
    | Sort-Object -Property Count -Descending

If you get an error saying "An empty pipe element is not allowed" then make sure that there is not a space after one of the backticks. The backtick is the continuation character, and tells PowerShell to keep processing the command on the next line, and if there is a space after it, the interpreter will get confused.

If everything works as expected, you should see output similar to the following:

Count Name                    
—– —-                    
  222 Dell Inc., OptiPlex 780 
  136 Dell Inc., OptiPlex GX620

  135 Dell Inc., OptiPlex 755 
  134 Dell Inc., OptiPlex 745 
  101 Dell Inc., OptiPlex GX280

There will also be a “group” property, which contains the actual .NET objects that were grouped into each line item.

Hope this helps!

Posted in configmgr, powershell, scripting, tools, wmi | Tagged: , , , , , , , , , , , , | Leave a Comment »

PowerShell: Ping Host List from Text File

Posted by Trevor Sullivan on 2011/10/26

Here’s a quick PowerShell script to ping a list of hosts (computers, or other IP endpoints) from a text file. In addition, it eliminates error messages, which results in a filtered list of hosts that are alive. It runs quickly, because the ping count has been restricted to 1, from the default of 4.

foreach ($Client in Get-Content -Path (Read-Host).Replace('"',''))
    Test-Connection -ComputerName $Client.Trim() -Count 1 -ErrorAction SilentlyContinue

The reason it has the call to the String.Replace() method is because, if you use the Copy as Path feature in Windows 7 Explorer to feed the input to the script, it includes double quotes around the path. In this script, we don’t actually need the double quotes, because that will confuse the Get-Content cmdlet’s –Path parameter.

The call the String.Trim() is present because in my test input text file, some computer names had whitespace after them; this call cleans that up.

Posted in powershell, scripting, tools | Tagged: , , , , , | Leave a Comment »

PowerShell: Update your ConfigMgr OSD Boot Images to WinPE 3.1

Posted by Trevor Sullivan on 2011/10/21

When you upgrade your boot images in Microsoft’s System Center Configuration Manager (SCCM / ConfigMgr) 2007 from WinPE 3.0 to WinPE 3.1, you must run the ExportDefaultBootImage() WMI method on the SMS_BootImagePackage WMI class for each boot image architecture. Typically this would simply include x86 (32-bit) and x64 (64-bit) boot images (Windows Image Format (WIM) files).

There are a few different methods of running this WMI method:

  • Manually through wbemtest
  • Using the VBscript scripting language
  • A PowerShell script

Since the first two methods have been covered already by other people, I will show an example of using Windows PowerShell to call the method. Simply replace the SCCMServer and SiteCode variables with the appropriate values, and WIM paths with your own, and run the script.

$SccmServer = 'MySccmServer'
$SiteCode = '123'
$BootImageClass = [wmiclass]"\\$SccmServer\root\sms\site_$SiteCode`:SMS_BootImagePackage"

$WimFiles = @{
    'x86' = '\\$SccmServer\SMS_$SiteCode\OSD\boot\i386\winpe.x86.3.1.wim' 
    'x64' = '\\$SccmServer\SMS_$SiteCode\OSD\boot\x64\winpe.x64.3.1.wim'

$BootImageClass.ExportDefaultBootImage('x64' , 1, $WimFiles.x64)
$BootImageClass.ExportDefaultBootImage('x86' , 1, $WimFiles.x86)

Posted in configmgr, OSD, powershell, scripting, wmi | Tagged: , , , , , , , , , | Leave a Comment »

PowerShell 3.0: List of Windows 8 Cmdlets & Modules

Posted by Trevor Sullivan on 2011/09/14

Here is a list of modules available in the new Windows Server 8:



Read the rest of this entry »

Posted in .NET, powershell, scripting, Windows 8 | Tagged: , , , , , , | Leave a Comment »

PowerShell: Determine Number of Parameters on Cmdlets

Posted by Trevor Sullivan on 2011/08/17

In PowerShell, each “cmdlet” has input and output parameters. Cmdlet definitions (including their names, parameters, parameters sets, attributes, etc.) are rich objects, just like every other object in PowerShell. Because of this, we can easily find out which cmdlets have the most parameters.

We follow this process to retrieve the information mentioned above:

  1. Retrieve a list of cmdlets available in the current PowerShell session
  2. Select the Name and parameter count (the latter, using a “calculated property” expression)
  3. Sort the results descending by parameter count

Get-Command -CommandType cmdlet | Select-Object -Property Name,@{Name = 'Parameter Count';Expression = {[int]$_.Parameters.Count} } | sort 'Parameter Count' –Descending

Here is what the results look like:

Name                                                                                                    Parameter Count
—-                                                                                                    —————
New-ModuleManifest                                                                                                   38
New-PSSessionOption                                                                                                  28
Invoke-Command                                                                                                       28
Get-WSManInstance                                                                                                    28
Get-WmiObject                                                                                                        26
Set-WmiInstance                                                                                                      25
Invoke-WmiMethod                                                                                                     25
Set-WSManInstance                                                                                                    24
Register-PSSessionConfiguration                                                                                      24
Remove-WmiObject                                                                                                     23
Enter-PSSession                                                                                                      23
Import-Module                                                                                                        23
Add-Type                                                                                                             23
Invoke-WSManAction                                                                                                   23
Set-PSSessionConfiguration                                                                                           23
Copy-Item                                                                                                            22
Set-ItemProperty                                                                                                     22
New-WSManInstance                                                                                                    22
Start-Process                                                                                                        22
Get-EventLog                                                                                                         22
New-PSSession                                                                                                        22
Send-MailMessage                                                                                                     22
Rename-ItemProperty                                                                                                  21
Get-Content                                                                                                          21

Posted in powershell | Tagged: , , , , , | Leave a Comment »

PowerShell: Happy Wifi Day!

Posted by Trevor Sullivan on 2011/08/02

PowerShell wishes you a happy Wifi day!

"Happy $(Get-Date –Format 'Mdd.yy') day!"


Posted in powershell, scripting | Tagged: , , , , , | Leave a Comment »

PowerShell / ConfigMgr: Sendsched.vbs Replacement

Posted by Trevor Sullivan on 2011/07/25

Recently, someone posted a PowerShell script, which is intended as a replacement for the SendSched.vbs included in the Microsoft System Center Configuration Manager 2007 Toolkit v2.

I took the liberty of cleaning the code up a little bit, and simplifying it to be more PowerShell friendly. Enjoy.

# Script Name: SendSched_PowerShell_Version.ps1
# Purpose: Serves as a replacement for the sendsched.vbs script included in the Microsoft System Center
#            Configuration Manager 2007 toolkit -- asynchronously invokes SCCM client tasks
# Created By Kaido Jarvemets Http://            
# Configuration Manager MVP            
# 25.07.2011

# Updated by: Trevor Sullivan
#      Email:
#         Blog:
#        Date: 2011-07-25
# Changelog:
#        * Replaced Get-ScheduleID function with a hashtable
#        * Removed custom ping function in favor of using Test-Connection
#        * Replaced default computer name with a period, which represents localhost
function Invoke-SCCMSchedule            
        [String]$ComputerName = ".",
        [Parameter(Mandatory = $true)]            
    $ScheduleIds = @{
        HardwareInventory    = "{00000000-0000-0000-0000-000000000001}"; # Hardware Inventory Collection Task             
        SoftwareInventory    = "{00000000-0000-0000-0000-000000000002}"; # Software Inventory Collection Task             
        HeartbeatDiscovery    = "{00000000-0000-0000-0000-000000000003}"; # Heartbeat Discovery Cycle             
        SoftwareInventoryFileCollection    = "{00000000-0000-0000-0000-000000000010}"; # Software Inventory File Collection Task             
        RequestMachinePolicy    = "{00000000-0000-0000-0000-000000000021}"; # Request Machine Policy Assignments             
        EvaluateMachinePolicy    = "{00000000-0000-0000-0000-000000000022}"; # Evaluate Machine Policy Assignments             
        RefreshDefaultMp    = "{00000000-0000-0000-0000-000000000023}"; # Refresh Default MP Task             
        RefreshLocationServices    = "{00000000-0000-0000-0000-000000000024}"; # Refresh Location Services Task             
        LocationServicesCleanup    = "{00000000-0000-0000-0000-000000000025}"; # Location Services Cleanup Task             
        SoftwareMeteringReport    = "{00000000-0000-0000-0000-000000000031}"; # Software Metering Report Cycle             
        SourceUpdate            = "{00000000-0000-0000-0000-000000000032}"; # Source Update Manage Update Cycle             
        PolicyAgentCleanup        = "{00000000-0000-0000-0000-000000000040}"; # Policy Agent Cleanup Cycle             
        RequestMachinePolicy2    = "{00000000-0000-0000-0000-000000000042}"; # Request Machine Policy Assignments             
        CertificateMaintenance    = "{00000000-0000-0000-0000-000000000051}"; # Certificate Maintenance Cycle             
        PeerDistributionPointStatus    = "{00000000-0000-0000-0000-000000000061}"; # Peer Distribution Point Status Task             
        PeerDistributionPointProvisioning    = "{00000000-0000-0000-0000-000000000062}"; # Peer Distribution Point Provisioning Status Task             
        ComplianceIntervalEnforcement    = "{00000000-0000-0000-0000-000000000071}"; # Compliance Interval Enforcement             
        SoftwareUpdatesAgentAssignmentEvaluation    = "{00000000-0000-0000-0000-000000000108}"; # Software Updates Agent Assignment Evaluation Cycle             
        UploadStateMessage    = "{00000000-0000-0000-0000-000000000111}"; # Send Unsent State Messages             
        StateMessageManager    = "{00000000-0000-0000-0000-000000000112}"; # State Message Manager Task             
        SoftwareUpdatesScan    = "{00000000-0000-0000-0000-000000000113}"; # Force Update Scan            
        AMTProvisionCycle    = "{00000000-0000-0000-0000-000000000120}"; # AMT Provision Cycle            
    if(Test-Connection -Computer $ComputerName) {
        Try {
            $SmsClient = [wmiclass]"\\$ComputerName\root\ccm`:SMS_Client"
        Catch {
            Write-Host "Trigger Schedule Method failed" -ForegroundColor RED            
    else {
        Write-Host "Computer may be offline or please check Windows Firewall settings" -ForegroundColor Red
}# End of Function Invoke-SCCMSchedule

Posted in configmgr, powershell, scripting, tools, wmi | Tagged: , , , , , , , , , | Leave a Comment »

PowerShell / ConfigMgr 2012: Check Client Reboot Pending State

Posted by Trevor Sullivan on 2011/07/25


If you’ve worked with Configuration Manager 2007 for very long, you probably know that clients pending reboots can cause you quite a headache. Determining whether or not a client needs a reboot can be a challenging task, and most folks used desired configuration management rules to detect it.

Well, I’m happy to announce that there’s a new method of figuring out whether or not a SCCM client requires a reboot! There’s a new WMI namespace called root\ccm\ClientSDK, and within it is a WMI class called CCM_ClientUtilities, which has a static method called DetermineIfRebootPending() – the method does not take any input parameters, however it spits out several [out] parameters when it is called.

Read the rest of this entry »

Posted in configmgr, ConfigMgr vNext, powershell, scripting, wmi | Tagged: , , , , , , , , , , , | Leave a Comment »

Links to Interesting Stuff

Posted by Trevor Sullivan on 2011/07/23

Updated on 2011-08-03

Here are some links to interesting blogs, software, and other random tidbits!

Read the rest of this entry »

Posted in Uncategorized | Tagged: , , , , , | Leave a Comment »