3

I am trying to process a flag from the MECM command Get-CMTaskSequenceDeployment called 'AdvertFlags'.

The information from Microsoft in relation to this value is HERE

The value returned is designated as : Data type: UInt32

In the table of flags, the one I need to check is listed as :

Hexadecimal (Bit) Description
0x00000020 (5) IMMEDIATE. Announce the advertisement to the user immediately.

As part of my Powershell script I am trying to ascertain if this flag is set.

I can see by converting it to Binary that a particular bit gets set.

When the settings is enabled:

DRIVE:\> [convert]::ToString((Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags, 2) 
100110010000000000100000

When the setting is disabled:

DRIVE:\> [convert]::ToString((Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags, 2) 
100110010000000000000000

The 6th bit is changed. Great! So far though, I've been unable to find a way to check if this bit is set. I suspected something in the bitwise operators (-band -bor etc) would help me here but I've been unable to get it to work.

Any bitwise operation I try returns an error:

"System.UInt64". Error: "Value was either too large or too small for a UInt64."

I mean, I can compare the string literally, but other options may be changed at any point.

Any help greatly appreciated.

EDIT: Just as an example of the error I am seeing, I can see that the bit that is set is '32' and from my limited understanding I should be able to:

PS:\> '100110010000000000100000' -band '32'
Cannot convert value "100110010000000000100000" to type "System.UInt64". Error: "Value was either too large or too small for a UInt64."
At line:1 char:1
+ '100110010000000000100000' -band '32'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastIConvertible

But I just always return an error

1
  • 1
    Wouldn't $enabled = [bool]((Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags -band 32) give you the wanted result? Commented Aug 19, 2022 at 11:12

2 Answers 2

5

To test bit6 in

$AdvertFlags = (Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags

Should simply be:

if ($AdvertFlags -band 32) { 'bit6 is set' } else { 'bit6 is not set' }

I do not have access to a deployment environment with Get-CMTaskSequenceDeployment cmdlet, nevertheless to confirm what I am stating:

$AdvertFlags = [Convert]::ToUInt32("100110010000000000100000", 2)
$AdvertFlags
10027040
if ($AdvertFlags -band 32) { 'bit6 is set' } else { 'bit6 is not set' }
bit6 is set
$AdvertFlags = [Convert]::ToUInt32("100110010000000000000000", 2)
$AdvertFlags
10027008
if ($AdvertFlags -band 32) { 'bit6 is set' } else { 'bit6 is not set' }
bit6 is not set

Your self-answer using [bigint]'100110010000000000100000' -band "32" to test for bit6 is merely a coincident that it returns the expected value:

10027035..10027045 |ForEach-Object {
    $Binary = [convert]::ToString($_, 2)
    [pscustomobject]@{
        Binary = $Binary
        bAnd   = $_ -bAnd 32
        Bigint = [bigint]$Binary -band "32"
    }
}

Yields:

Binary                   bAnd Bigint
------                   ---- ------
100110010000000000011011    0      0
100110010000000000011100    0      0
100110010000000000011101    0      0
100110010000000000011110    0     32 # ← incorrect
100110010000000000011111    0     32 # ← incorrect
100110010000000000100000   32     32
100110010000000000100001   32     32
100110010000000000100010   32     32
100110010000000000100011   32     32
100110010000000000100100   32      0 # ← incorrect
100110010000000000100101   32      0 # ← incorrect

enumerations as flags

But PowerShell has an even nicer way to test them by name:

[Flags()] enum AdvertFlags {
    IMMEDIATE                         = 0x00000020 # Announce the advertisement to the user immediately.
    ONSYSTEMSTARTUP                   = 0x00000100 # Announce the advertisement to the user on system startup.
    ONUSERLOGON                       = 0x00000200 # Announce the advertisement to the user on logon.
    ONUSERLOGOFF                      = 0x00000400 # Announce the advertisement to the user on logoff.
    OPTIONALPREDOWNLOAD               = 0x00001000 # If the selected architecture and language matches that of the client, the package content will be downloaded in advance
    WINDOWS_CE                        = 0x00008000 # The advertisement is for a device client.
    ENABLE_PEER_CACHING               = 0x00010000 # This information applies to System Center 2012 Configuration Manager SP1 or later, and System Center 2012 R2 Configuration Manager or later.
    DONOT_FALLBACK                    = 0x00020000 # Do not fall back to unprotected distribution points.
    ENABLE_TS_FROM_CD_AND_PXE         = 0x00040000 # The task sequence is available to removable media and the pre-boot execution environment (PXE) service point.
    APTSINTRANETONLY                  = 0x00080000 #
    OVERRIDE_SERVICE_WINDOWS          = 0x00100000 # Override maintenance windows in announcing the advertisement to the user.
    REBOOT_OUTSIDE_OF_SERVICE_WINDOWS = 0x00200000 # Reboot outside of maintenance windows.
    WAKE_ON_LAN_ENABLED               = 0x00400000 # Announce the advertisement to the user with Wake On LAN enabled.
    SHOW_PROGRESS                     = 0x00800000 # Announce the advertisement to the user showing task sequence progress.
    NO_DISPLAY                        = 0x02000000 # The user should not run programs independently of the assignment.
    ONSLOWNET                         = 0x04000000 # Assignments are mandatory over a slow network connection.
    TARGETTOWINPE                     = 0x10000000 # Target this deployment to WinPE only.
    HIDDENINWINPE                     = 0x20000000 # Target this deployment to WinPE only but hide in WinPE. It can only be used by TS variable SMSTSPreferredAdvertID.
}

# $AdvertFlags = [AdvertFlags](Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags
$AdvertFlags = [AdvertFlags][Convert]::ToUInt32("100110010000000000100000", 2)
# or: $AdvertFlags = [AdvertFlags]('IMMEDIATE', 'ENABLE_PEER_CACHING', 'APTSINTRANETONLY', 'OVERRIDE_SERVICE_WINDOWS', 'SHOW_PROGRESS')
$AdvertFlags
IMMEDIATE, ENABLE_PEER_CACHING, APTSINTRANETONLY, OVERRIDE_SERVICE_WINDOWS, SHOW_PROGRESS
$AdvertFlags -bAnd [AdvertFlags]'IMMEDIATE'
IMMEDIATE
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, thanks for the in-depth response. I'll test it out today and mark as answered. When I found my answer I suspected that it might not be correct. Thanks again!
1

EDIT: My answer here is incorrect as noted above. Leaving here for prosperity!

As always I BELEIVE I found the answer minutes after posting (After spending a couple hours on this!).

By adjusting the type to [bigint] the comparison was able to complete and return the expected answer:

DRIVE:\> [bigint]'100110010000000000100000' -band "32"
32

So a simple:

If (([bigint]'100110010000000000100000' -band "32") -gt 0){$true}else{$false}
True

and:

If (([bigint]'100110010000000000000000' -band "32") -gt 0){$true}else{$false}
False

Solves my issue. Feel free to give any extra advice if this is not the ideal way to proceed.

I though PS would be smarted when auto defining types etc. This is targeting PS5 on Server 2012 R2 though.

1 Comment

You can do it without converting the flags to string: if( (Get-CMTaskSequenceDeployment -AdvertisementID ABC20723).AdvertFlags -band 0x20) ) {$true} else {$false}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.