none
Insert a command for pop up message RRS feed

  • Question

  • Hello All,

    Seeking help from the community to include a pop up message when techs execute the script on local machine.  The script runs few actions in Control Panel - Configuration Manager.  Now the script does a job but it is not displaying a message when they run the script.  I was able to Google and get the command details but not sure where to insert the command within the script.

    The command is

    [System.Windows.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')

    The script is 

    function Start-CMClientAction {
        <#
    .SYNOPSIS
        Invokes CM Client actions on local or remote machines

    .DESCRIPTION
        This script will allow you to invoke a set of CM Client actions on a machine (with optional credentials), providing a list of the actions and an optional delay betweens actions. 
        The function will attempt for a default of 5 minutes to invoke the action, with a 10 second delay inbetween attempts. This is to account for invoke-wmimethod failures.

    .PARAMETER Schedule
    Define the schedules to run on the machine - 'HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR'

    .PARAMETER Delay
    Specify the delay in seconds between each schedule when more than one is ran - 0-30 seconds

    .PARAMETER ComputerName
        Specifies the computers to run this against
        
    .PARAMETER Timeout
        Specifies the timeout in minutes after which any individual computer will stop attempting the schedules. Default is 5 minutes.

    .PARAMETER Credential
    Optional PSCredential

    .EXAMPLE
    # Start a machine policy eval and a hardware inventory cycle
    Start-CMClientAction -Schedule MachinePol,HardwareInv

    .NOTES
        FileName:    Start-CMClientAction.ps1
        Author:      Cody Mathis
        Contact:     @CodyMathis123
        Created:     11-29-2018
        Updated:     03-09-2019
    #>
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
            [Alias('Computer', 'HostName', 'ServerName', 'IPAddress')]
            [string[]]$ComputerName = $env:COMPUTERNAME,
            [parameter(Mandatory = $true)]
            [ValidateSet('HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR')]
            [string[]]$Schedule,
            [parameter(Mandatory = $false)]
            [ValidateRange(0, 30)]
            [int]$Delay = 5,
            [parameter(Mandatory = $false)]
            [int]$Timeout = 5,
            [parameter(Mandatory = $false)]
            [pscredential]$Credential
        )
        begin {
            $TimeSpan = New-TimeSpan -Minutes $Timeout
        }
        process {
            foreach ($Computer in $ComputerName) {
                foreach ($Option in $Schedule) {
                    $Action = switch -Regex ($Option) {
                        '^HardwareInv$|^FullHardwareInv$' {
                            '{00000000-0000-0000-0000-000000000001}'
                        }
                        '^SoftwareInv$' {
                            '{00000000-0000-0000-0000-000000000002}'
                        }
                        '^UpdateScan$' {
                            '{00000000-0000-0000-0000-000000000113}'
                        }
                        '^UpdateEval$' {
                            '{00000000-0000-0000-0000-000000000108}'
                        }
                        '^MachinePol$' {
                            '{00000000-0000-0000-0000-000000000021}'
                        }
                        '^AppEval$' {
                            '{00000000-0000-0000-0000-000000000121}'
                        }
                        '^DDR$' {
                            '{00000000-0000-0000-0000-000000000003}'
                        }
                    }

                    $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    do {
                        try {
                            Remove-Variable MustExit -ErrorAction SilentlyContinue
                            Remove-Variable Invocation -ErrorAction SilentlyContinue
                            if ($Option -eq 'FullHardwareInv') {
                                $getWMIObjectSplat = @{
                                    ComputerName = $Computer
                                    Namespace    = 'root\ccm\invagt'
                                    Class        = 'InventoryActionStatus'
                                    Filter       = "InventoryActionID ='$Action'"
                                    ErrorAction  = 'Stop'
                                }
                                if ($PSBoundParameters.ContainsKey('Credential')) {
                                    $getWMIObjectSplat.Add('Credential', $Credential)
                                }
                                Write-Verbose "Attempting to delete Hardware Inventory history for $Computer as a FullHardwareInv was requested"
                                $HWInv = Get-WMIObject @getWMIObjectSplat
                                if ($null -ne $HWInv) {
                                    $HWInv.Delete()
                                    Write-Verbose "Hardware Inventory history deleted for $Computer"
                                }
                                else {
                                    Write-Verbose "No Hardware Inventory history to delete for $Computer"
                                }
                            }
                            $invokeWmiMethodSplat = @{
                                ComputerName = $Computer
                                Name         = 'TriggerSchedule'
                                Namespace    = 'root\ccm'
                                Class        = 'sms_client'
                                ArgumentList = $Action
                                ErrorAction  = 'Stop'
                            }
                            if ($PSBoundParameters.ContainsKey('Credential')) {
                                $invokeWmiMethodSplat.Add('Credential', $Credential)
                            }
                            Write-Verbose "Triggering a $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                            $Invocation = Invoke-WmiMethod @invokeWmiMethodSplat
                        }
                        catch [System.UnauthorizedAccessException] {
                            Write-Error -Message "Access denied to $Computer" -Category AuthenticationError -Exception $_.Exception
                            $MustExit = $true
                        }
                        catch {
                            Write-Warning "Failed to invoke the $Option cycle via WMI. Will retry every 10 seconds until [StopWatch $($StopWatch.Elapsed) -ge $Timeout minutes] Error: $($_.Exception.Message)"
                            Start-Sleep -Seconds 10
                        }
                    }
                    until ($Invocation -or $StopWatch.Elapsed -ge $TimeSpan -or $MustExit)
                    if ($Invocation) {
                        Write-Verbose "Successfully invoked the $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                        Start-Sleep -Seconds $Delay
                    }
                    elseif ($StopWatch.Elapsed -ge $TimeSpan) {
                        Write-Error "Failed to invoke $Option cycle via WMI after $Timeout minutes of retrrying."
                    }
                    $StopWatch.Reset()    
                }
            }
        }
        end {
            Write-Verbose "Following actions invoked - $Schedule"
        }
    }

    Tuesday, July 16, 2019 1:31 PM

Answers

  • Add-Type -AssemblyName System.Windows.Forms
    
     
    
    
    function Start-CMClientAction {
        <#
    .SYNOPSIS
        Invokes CM Client actions on local or remote machines
    
    .DESCRIPTION
        This script will allow you to invoke a set of CM Client actions on a machine (with optional credentials), providing a list of the actions and an optional delay betweens actions. 
        The function will attempt for a default of 5 minutes to invoke the action, with a 10 second delay inbetween attempts. This is to account for invoke-wmimethod failures.
    
    .PARAMETER Schedule
    Define the schedules to run on the machine - 'HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR'
    
    .PARAMETER Delay
    Specify the delay in seconds between each schedule when more than one is ran - 0-30 seconds
    
    .PARAMETER ComputerName
        Specifies the computers to run this against
        
    .PARAMETER Timeout
        Specifies the timeout in minutes after which any individual computer will stop attempting the schedules. Default is 5 minutes.
    
    .PARAMETER Credential
    Optional PSCredential
    
    .EXAMPLE
    # Start a machine policy eval and a hardware inventory cycle
    Start-CMClientAction -Schedule MachinePol,HardwareInv
    
    .NOTES
        FileName:    Start-CMClientAction.ps1
        Author:      Cody Mathis
        Contact:     @CodyMathis123
        Created:     11-29-2018
        Updated:     03-09-2019
    #>
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
            [Alias('Computer', 'HostName', 'ServerName', 'IPAddress')]
            [string[]]$ComputerName = $env:COMPUTERNAME,
            [parameter(Mandatory = $true)]
            [ValidateSet('HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR')]
            [string[]]$Schedule,
            [parameter(Mandatory = $false)]
            [ValidateRange(0, 30)]
            [int]$Delay = 5,
            [parameter(Mandatory = $false)]
            [int]$Timeout = 5,
            [parameter(Mandatory = $false)]
            [pscredential]$Credential
        )
        begin {
            $TimeSpan = New-TimeSpan -Minutes $Timeout
        }
        process {
            foreach ($Computer in $ComputerName) {
                foreach ($Option in $Schedule) {
                    $Action = switch -Regex ($Option) {
                        '^HardwareInv$|^FullHardwareInv$' {
                            '{00000000-0000-0000-0000-000000000001}'
                        }
                        '^SoftwareInv$' {
                            '{00000000-0000-0000-0000-000000000002}'
                        }
                        '^UpdateScan$' {
                            '{00000000-0000-0000-0000-000000000113}'
                        }
                        '^UpdateEval$' {
                            '{00000000-0000-0000-0000-000000000108}'
                        }
                        '^MachinePol$' {
                            '{00000000-0000-0000-0000-000000000021}'
                        }
                        '^AppEval$' {
                            '{00000000-0000-0000-0000-000000000121}'
                        }
                        '^DDR$' {
                            '{00000000-0000-0000-0000-000000000003}'
                        }
                    }
    
                    $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    do {
                        try {
                            Remove-Variable MustExit -ErrorAction SilentlyContinue
                            Remove-Variable Invocation -ErrorAction SilentlyContinue
                            if ($Option -eq 'FullHardwareInv') {
                                $getWMIObjectSplat = @{
                                    ComputerName = $Computer
                                    Namespace    = 'root\ccm\invagt'
                                    Class        = 'InventoryActionStatus'
                                    Filter       = "InventoryActionID ='$Action'"
                                    ErrorAction  = 'Stop'
                                }
                                if ($PSBoundParameters.ContainsKey('Credential')) {
                                    $getWMIObjectSplat.Add('Credential', $Credential)
                                }
                                Write-Verbose "Attempting to delete Hardware Inventory history for $Computer as a FullHardwareInv was requested"
                                $HWInv = Get-WMIObject @getWMIObjectSplat
                                if ($null -ne $HWInv) {
                                    $HWInv.Delete()
                                    Write-Verbose "Hardware Inventory history deleted for $Computer"
                                }
                                else {
                                    Write-Verbose "No Hardware Inventory history to delete for $Computer"
                                }
                            }
                            $invokeWmiMethodSplat = @{
                                ComputerName = $Computer
                                Name         = 'TriggerSchedule'
                                Namespace    = 'root\ccm'
                                Class        = 'sms_client'
                                ArgumentList = $Action
                                ErrorAction  = 'Stop'
                            }
                            if ($PSBoundParameters.ContainsKey('Credential')) {
                                $invokeWmiMethodSplat.Add('Credential', $Credential)
                            }
                            Write-Verbose "Triggering a $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                            $Invocation = Invoke-WmiMethod @invokeWmiMethodSplat
                        }
                        catch [System.UnauthorizedAccessException] {
                            Write-Error -Message "Access denied to $Computer" -Category AuthenticationError -Exception $_.Exception
                            $MustExit = $true
                        }
                        catch {
                            Write-Warning "Failed to invoke the $Option cycle via WMI. Will retry every 10 seconds until [StopWatch $($StopWatch.Elapsed) -ge $Timeout minutes] Error: $($_.Exception.Message)"
                            Start-Sleep -Seconds 10
                        }
                    }
                    until ($Invocation -or $StopWatch.Elapsed -ge $TimeSpan -or $MustExit)
                    if ($Invocation) {
                        Write-Verbose "Successfully invoked the $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                        Start-Sleep -Seconds $Delay
                    }
                    elseif ($StopWatch.Elapsed -ge $TimeSpan) {
                        Write-Error "Failed to invoke $Option cycle via WMI after $Timeout minutes of retrrying."
                    }
                    $StopWatch.Reset()    
                }
            }
        }
        end {
            Write-Verbose "Following actions invoked - $Schedule"
        }
    }
    
    
    
    [System.Windows.Forms.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')
    
    #Call your function here 

    • Marked as answer by LANHD Wednesday, July 17, 2019 2:16 PM
    Tuesday, July 16, 2019 3:57 PM

All replies

  • Use it before you call the Start-CMClientAction function. Something like:

    function Start-CMClientAction {
        <#
    .SYNOPSIS
        Invokes CM Client actions on local or remote machines
    
    .DESCRIPTION
        This script will allow you to invoke a set of CM Client actions on a machine (with optional credentials), providing a list of the actions and an optional delay betweens actions. 
        The function will attempt for a default of 5 minutes to invoke the action, with a 10 second delay inbetween attempts. This is to account for invoke-wmimethod failures.
    
    .PARAMETER Schedule
    Define the schedules to run on the machine - 'HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR'
    
    .PARAMETER Delay
    Specify the delay in seconds between each schedule when more than one is ran - 0-30 seconds
    
    .PARAMETER ComputerName
        Specifies the computers to run this against
        
    .PARAMETER Timeout
        Specifies the timeout in minutes after which any individual computer will stop attempting the schedules. Default is 5 minutes.
    
    .PARAMETER Credential
    Optional PSCredential
    
    .EXAMPLE
    # Start a machine policy eval and a hardware inventory cycle
    Start-CMClientAction -Schedule MachinePol,HardwareInv
    
    .NOTES
        FileName:    Start-CMClientAction.ps1
        Author:      Cody Mathis
        Contact:     @CodyMathis123
        Created:     11-29-2018
        Updated:     03-09-2019
    #>
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
            [Alias('Computer', 'HostName', 'ServerName', 'IPAddress')]
            [string[]]$ComputerName = $env:COMPUTERNAME,
            [parameter(Mandatory = $true)]
            [ValidateSet('HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR')]
            [string[]]$Schedule,
            [parameter(Mandatory = $false)]
            [ValidateRange(0, 30)]
            [int]$Delay = 5,
            [parameter(Mandatory = $false)]
            [int]$Timeout = 5,
            [parameter(Mandatory = $false)]
            [pscredential]$Credential
        )
        begin {
            $TimeSpan = New-TimeSpan -Minutes $Timeout
        }
        process {
            foreach ($Computer in $ComputerName) {
                foreach ($Option in $Schedule) {
                    $Action = switch -Regex ($Option) {
                        '^HardwareInv$|^FullHardwareInv$' {
                            '{00000000-0000-0000-0000-000000000001}'
                        }
                        '^SoftwareInv$' {
                            '{00000000-0000-0000-0000-000000000002}'
                        }
                        '^UpdateScan$' {
                            '{00000000-0000-0000-0000-000000000113}'
                        }
                        '^UpdateEval$' {
                            '{00000000-0000-0000-0000-000000000108}'
                        }
                        '^MachinePol$' {
                            '{00000000-0000-0000-0000-000000000021}'
                        }
                        '^AppEval$' {
                            '{00000000-0000-0000-0000-000000000121}'
                        }
                        '^DDR$' {
                            '{00000000-0000-0000-0000-000000000003}'
                        }
                    }
    
                    $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    do {
                        try {
                            Remove-Variable MustExit -ErrorAction SilentlyContinue
                            Remove-Variable Invocation -ErrorAction SilentlyContinue
                            if ($Option -eq 'FullHardwareInv') {
                                $getWMIObjectSplat = @{
                                    ComputerName = $Computer
                                    Namespace    = 'root\ccm\invagt'
                                    Class        = 'InventoryActionStatus'
                                    Filter       = "InventoryActionID ='$Action'"
                                    ErrorAction  = 'Stop'
                                }
                                if ($PSBoundParameters.ContainsKey('Credential')) {
                                    $getWMIObjectSplat.Add('Credential', $Credential)
                                }
                                Write-Verbose "Attempting to delete Hardware Inventory history for $Computer as a FullHardwareInv was requested"
                                $HWInv = Get-WMIObject @getWMIObjectSplat
                                if ($null -ne $HWInv) {
                                    $HWInv.Delete()
                                    Write-Verbose "Hardware Inventory history deleted for $Computer"
                                }
                                else {
                                    Write-Verbose "No Hardware Inventory history to delete for $Computer"
                                }
                            }
                            $invokeWmiMethodSplat = @{
                                ComputerName = $Computer
                                Name         = 'TriggerSchedule'
                                Namespace    = 'root\ccm'
                                Class        = 'sms_client'
                                ArgumentList = $Action
                                ErrorAction  = 'Stop'
                            }
                            if ($PSBoundParameters.ContainsKey('Credential')) {
                                $invokeWmiMethodSplat.Add('Credential', $Credential)
                            }
                            Write-Verbose "Triggering a $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                            $Invocation = Invoke-WmiMethod @invokeWmiMethodSplat
                        }
                        catch [System.UnauthorizedAccessException] {
                            Write-Error -Message "Access denied to $Computer" -Category AuthenticationError -Exception $_.Exception
                            $MustExit = $true
                        }
                        catch {
                            Write-Warning "Failed to invoke the $Option cycle via WMI. Will retry every 10 seconds until [StopWatch $($StopWatch.Elapsed) -ge $Timeout minutes] Error: $($_.Exception.Message)"
                            Start-Sleep -Seconds 10
                        }
                    }
                    until ($Invocation -or $StopWatch.Elapsed -ge $TimeSpan -or $MustExit)
                    if ($Invocation) {
                        Write-Verbose "Successfully invoked the $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                        Start-Sleep -Seconds $Delay
                    }
                    elseif ($StopWatch.Elapsed -ge $TimeSpan) {
                        Write-Error "Failed to invoke $Option cycle via WMI after $Timeout minutes of retrrying."
                    }
                    $StopWatch.Reset()    
                }
            }
        }
        end {
            Write-Verbose "Following actions invoked - $Schedule"
        }
    }
    
    
    
    [System.Windows.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')
    
    Start-CMClientAction.........

    Or inside the function in begin block:

    function Start-CMClientAction {
        <#
    .SYNOPSIS
        Invokes CM Client actions on local or remote machines
    
    .DESCRIPTION
        This script will allow you to invoke a set of CM Client actions on a machine (with optional credentials), providing a list of the actions and an optional delay betweens actions. 
        The function will attempt for a default of 5 minutes to invoke the action, with a 10 second delay inbetween attempts. This is to account for invoke-wmimethod failures.
    
    .PARAMETER Schedule
    Define the schedules to run on the machine - 'HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR'
    
    .PARAMETER Delay
    Specify the delay in seconds between each schedule when more than one is ran - 0-30 seconds
    
    .PARAMETER ComputerName
        Specifies the computers to run this against
        
    .PARAMETER Timeout
        Specifies the timeout in minutes after which any individual computer will stop attempting the schedules. Default is 5 minutes.
    
    .PARAMETER Credential
    Optional PSCredential
    
    .EXAMPLE
    # Start a machine policy eval and a hardware inventory cycle
    Start-CMClientAction -Schedule MachinePol,HardwareInv
    
    .NOTES
        FileName:    Start-CMClientAction.ps1
        Author:      Cody Mathis
        Contact:     @CodyMathis123
        Created:     11-29-2018
        Updated:     03-09-2019
    #>
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
            [Alias('Computer', 'HostName', 'ServerName', 'IPAddress')]
            [string[]]$ComputerName = $env:COMPUTERNAME,
            [parameter(Mandatory = $true)]
            [ValidateSet('HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR')]
            [string[]]$Schedule,
            [parameter(Mandatory = $false)]
            [ValidateRange(0, 30)]
            [int]$Delay = 5,
            [parameter(Mandatory = $false)]
            [int]$Timeout = 5,
            [parameter(Mandatory = $false)]
            [pscredential]$Credential
        )
        begin {
            [System.Windows.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')
            $TimeSpan = New-TimeSpan -Minutes $Timeout
        }
        process {
            foreach ($Computer in $ComputerName) {
                foreach ($Option in $Schedule) {
                    $Action = switch -Regex ($Option) {
                        '^HardwareInv$|^FullHardwareInv$' {
                            '{00000000-0000-0000-0000-000000000001}'
                        }
                        '^SoftwareInv$' {
                            '{00000000-0000-0000-0000-000000000002}'
                        }
                        '^UpdateScan$' {
                            '{00000000-0000-0000-0000-000000000113}'
                        }
                        '^UpdateEval$' {
                            '{00000000-0000-0000-0000-000000000108}'
                        }
                        '^MachinePol$' {
                            '{00000000-0000-0000-0000-000000000021}'
                        }
                        '^AppEval$' {
                            '{00000000-0000-0000-0000-000000000121}'
                        }
                        '^DDR$' {
                            '{00000000-0000-0000-0000-000000000003}'
                        }
                    }
    
                    $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    do {
                        try {
                            Remove-Variable MustExit -ErrorAction SilentlyContinue
                            Remove-Variable Invocation -ErrorAction SilentlyContinue
                            if ($Option -eq 'FullHardwareInv') {
                                $getWMIObjectSplat = @{
                                    ComputerName = $Computer
                                    Namespace    = 'root\ccm\invagt'
                                    Class        = 'InventoryActionStatus'
                                    Filter       = "InventoryActionID ='$Action'"
                                    ErrorAction  = 'Stop'
                                }
                                if ($PSBoundParameters.ContainsKey('Credential')) {
                                    $getWMIObjectSplat.Add('Credential', $Credential)
                                }
                                Write-Verbose "Attempting to delete Hardware Inventory history for $Computer as a FullHardwareInv was requested"
                                $HWInv = Get-WMIObject @getWMIObjectSplat
                                if ($null -ne $HWInv) {
                                    $HWInv.Delete()
                                    Write-Verbose "Hardware Inventory history deleted for $Computer"
                                }
                                else {
                                    Write-Verbose "No Hardware Inventory history to delete for $Computer"
                                }
                            }
                            $invokeWmiMethodSplat = @{
                                ComputerName = $Computer
                                Name         = 'TriggerSchedule'
                                Namespace    = 'root\ccm'
                                Class        = 'sms_client'
                                ArgumentList = $Action
                                ErrorAction  = 'Stop'
                            }
                            if ($PSBoundParameters.ContainsKey('Credential')) {
                                $invokeWmiMethodSplat.Add('Credential', $Credential)
                            }
                            Write-Verbose "Triggering a $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                            $Invocation = Invoke-WmiMethod @invokeWmiMethodSplat
                        }
                        catch [System.UnauthorizedAccessException] {
                            Write-Error -Message "Access denied to $Computer" -Category AuthenticationError -Exception $_.Exception
                            $MustExit = $true
                        }
                        catch {
                            Write-Warning "Failed to invoke the $Option cycle via WMI. Will retry every 10 seconds until [StopWatch $($StopWatch.Elapsed) -ge $Timeout minutes] Error: $($_.Exception.Message)"
                            Start-Sleep -Seconds 10
                        }
                    }
                    until ($Invocation -or $StopWatch.Elapsed -ge $TimeSpan -or $MustExit)
                    if ($Invocation) {
                        Write-Verbose "Successfully invoked the $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                        Start-Sleep -Seconds $Delay
                    }
                    elseif ($StopWatch.Elapsed -ge $TimeSpan) {
                        Write-Error "Failed to invoke $Option cycle via WMI after $Timeout minutes of retrrying."
                    }
                    $StopWatch.Reset()    
                }
            }
        }
        end {
            Write-Verbose "Following actions invoked - $Schedule"
        }
    }

    • Edited by DumbleD0re Tuesday, July 16, 2019 1:41 PM
    Tuesday, July 16, 2019 1:39 PM
  • Thanks DumbleD0re. 

    Is it possible to pop up the message after techs run the script.  That is what I am exactly looking for.  Now when the techs run the  script runs it work and returns to command prompt without any message.  So what, I am trying is to get a pop up message after they run the script.

    I tried saving your script and ran within PS ad Admin.  No pop up message at all.

    RL

    Tuesday, July 16, 2019 1:55 PM
  • Try using the below command:

    [System.Windows.Forms.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')
    

    You might also need to add the Forms type in starting, use the below command at the starting of the script for the same:

    Add-Type -AssemblyName System.Windows.Forms

    I have tried using the same using cmd and it worked.

    Tuesday, July 16, 2019 3:23 PM
  • Thanks once again.

    I added above command and tried within PS ISE as Admin.  It worked, however when, I try it as PS it gives me error.  Here is the screen shot.  Any chance you can share the updated script that, I can try it as PS.


    • Edited by LANHD Tuesday, July 16, 2019 3:45 PM
    Tuesday, July 16, 2019 3:40 PM
  • Add-Type -AssemblyName System.Windows.Forms
    
     
    
    
    function Start-CMClientAction {
        <#
    .SYNOPSIS
        Invokes CM Client actions on local or remote machines
    
    .DESCRIPTION
        This script will allow you to invoke a set of CM Client actions on a machine (with optional credentials), providing a list of the actions and an optional delay betweens actions. 
        The function will attempt for a default of 5 minutes to invoke the action, with a 10 second delay inbetween attempts. This is to account for invoke-wmimethod failures.
    
    .PARAMETER Schedule
    Define the schedules to run on the machine - 'HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR'
    
    .PARAMETER Delay
    Specify the delay in seconds between each schedule when more than one is ran - 0-30 seconds
    
    .PARAMETER ComputerName
        Specifies the computers to run this against
        
    .PARAMETER Timeout
        Specifies the timeout in minutes after which any individual computer will stop attempting the schedules. Default is 5 minutes.
    
    .PARAMETER Credential
    Optional PSCredential
    
    .EXAMPLE
    # Start a machine policy eval and a hardware inventory cycle
    Start-CMClientAction -Schedule MachinePol,HardwareInv
    
    .NOTES
        FileName:    Start-CMClientAction.ps1
        Author:      Cody Mathis
        Contact:     @CodyMathis123
        Created:     11-29-2018
        Updated:     03-09-2019
    #>
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
            [Alias('Computer', 'HostName', 'ServerName', 'IPAddress')]
            [string[]]$ComputerName = $env:COMPUTERNAME,
            [parameter(Mandatory = $true)]
            [ValidateSet('HardwareInv', 'FullHardwareInv', 'SoftwareInv', 'UpdateScan', 'UpdateEval', 'MachinePol', 'AppEval', 'DDR')]
            [string[]]$Schedule,
            [parameter(Mandatory = $false)]
            [ValidateRange(0, 30)]
            [int]$Delay = 5,
            [parameter(Mandatory = $false)]
            [int]$Timeout = 5,
            [parameter(Mandatory = $false)]
            [pscredential]$Credential
        )
        begin {
            $TimeSpan = New-TimeSpan -Minutes $Timeout
        }
        process {
            foreach ($Computer in $ComputerName) {
                foreach ($Option in $Schedule) {
                    $Action = switch -Regex ($Option) {
                        '^HardwareInv$|^FullHardwareInv$' {
                            '{00000000-0000-0000-0000-000000000001}'
                        }
                        '^SoftwareInv$' {
                            '{00000000-0000-0000-0000-000000000002}'
                        }
                        '^UpdateScan$' {
                            '{00000000-0000-0000-0000-000000000113}'
                        }
                        '^UpdateEval$' {
                            '{00000000-0000-0000-0000-000000000108}'
                        }
                        '^MachinePol$' {
                            '{00000000-0000-0000-0000-000000000021}'
                        }
                        '^AppEval$' {
                            '{00000000-0000-0000-0000-000000000121}'
                        }
                        '^DDR$' {
                            '{00000000-0000-0000-0000-000000000003}'
                        }
                    }
    
                    $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
                    do {
                        try {
                            Remove-Variable MustExit -ErrorAction SilentlyContinue
                            Remove-Variable Invocation -ErrorAction SilentlyContinue
                            if ($Option -eq 'FullHardwareInv') {
                                $getWMIObjectSplat = @{
                                    ComputerName = $Computer
                                    Namespace    = 'root\ccm\invagt'
                                    Class        = 'InventoryActionStatus'
                                    Filter       = "InventoryActionID ='$Action'"
                                    ErrorAction  = 'Stop'
                                }
                                if ($PSBoundParameters.ContainsKey('Credential')) {
                                    $getWMIObjectSplat.Add('Credential', $Credential)
                                }
                                Write-Verbose "Attempting to delete Hardware Inventory history for $Computer as a FullHardwareInv was requested"
                                $HWInv = Get-WMIObject @getWMIObjectSplat
                                if ($null -ne $HWInv) {
                                    $HWInv.Delete()
                                    Write-Verbose "Hardware Inventory history deleted for $Computer"
                                }
                                else {
                                    Write-Verbose "No Hardware Inventory history to delete for $Computer"
                                }
                            }
                            $invokeWmiMethodSplat = @{
                                ComputerName = $Computer
                                Name         = 'TriggerSchedule'
                                Namespace    = 'root\ccm'
                                Class        = 'sms_client'
                                ArgumentList = $Action
                                ErrorAction  = 'Stop'
                            }
                            if ($PSBoundParameters.ContainsKey('Credential')) {
                                $invokeWmiMethodSplat.Add('Credential', $Credential)
                            }
                            Write-Verbose "Triggering a $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                            $Invocation = Invoke-WmiMethod @invokeWmiMethodSplat
                        }
                        catch [System.UnauthorizedAccessException] {
                            Write-Error -Message "Access denied to $Computer" -Category AuthenticationError -Exception $_.Exception
                            $MustExit = $true
                        }
                        catch {
                            Write-Warning "Failed to invoke the $Option cycle via WMI. Will retry every 10 seconds until [StopWatch $($StopWatch.Elapsed) -ge $Timeout minutes] Error: $($_.Exception.Message)"
                            Start-Sleep -Seconds 10
                        }
                    }
                    until ($Invocation -or $StopWatch.Elapsed -ge $TimeSpan -or $MustExit)
                    if ($Invocation) {
                        Write-Verbose "Successfully invoked the $Option Cycle on $Computer via the 'TriggerSchedule' WMI method"
                        Start-Sleep -Seconds $Delay
                    }
                    elseif ($StopWatch.Elapsed -ge $TimeSpan) {
                        Write-Error "Failed to invoke $Option cycle via WMI after $Timeout minutes of retrrying."
                    }
                    $StopWatch.Reset()    
                }
            }
        }
        end {
            Write-Verbose "Following actions invoked - $Schedule"
        }
    }
    
    
    
    [System.Windows.Forms.MessageBox]::Show('Selected cycle will run and might take few minutes to finish')
    
    #Call your function here 

    • Marked as answer by LANHD Wednesday, July 17, 2019 2:16 PM
    Tuesday, July 16, 2019 3:57 PM
  • Amazing Friend.  It worked perfectly both PS and PS ISE.  Now, I can give this script to my techs who will be happy to run and see pop message.

    Thanks for all the help.

    RL




    • Edited by LANHD Wednesday, July 17, 2019 2:16 PM
    Wednesday, July 17, 2019 12:16 PM
  • Please mark the solution that worked for you as answered so that it may help others too.
    Wednesday, July 17, 2019 12:38 PM
  • Could you please post what have you written inside test 3.ps1
    Wednesday, July 17, 2019 1:25 PM
  • Please ignore previous message.  My mistake with typo.  I guess I can't type properly.  It works fine now.  I will mark it as answered.  If anybody wants the script - I will post later.

    Thanks for all the help.

    RL

    Wednesday, July 17, 2019 1:52 PM