This is a follow up on my previous article perform all the SCCM Client Actions with vbscript. Now, I have chosen a different approach: a PowerShell form where you can select the actions you want to perform. The interface is also multilingual. It supports English (fall back language), French, German, Dutch and Spanish. If your OS is in one of these languages, then the interface is in the same language. Otherwise, it is English. You can also overrule the language.
Before we start, one of the challenges I had. I used the following WMI command first:
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule {00000000-0000-0000-0000-000000000001}
And I received the following error message:
So that was a no-go.
Therefore, I decided to use the same technique as with vbscript:
$CPApplet = New-Object -Comobject CPApplet.CPAppletMgr
$Actions = $CPApplet.GetClientActions()
ForEach ($Action in $Actions)
{
$Action.PerformAction()
}
No errors, and a working solution. Just 6 lines of code.
But I wanted some additional features:
- A nice GUI
- Select the SCCM actions you want to perform
- Select all the SCCM actions you want to perform
- Lock the user interface
- A log file
- Select or unselect all the SCCM actions
- Silent option, without a GUI
- Multilingual
- Last but not least: an error message if the SCCM client is not working fine.
In version 0.2 two new options have been implemented:
- An option to see the SCCM Client Properties, like client version, management point and site.
- An option to see the SCCM Client Components and its version.
In version 0.4 an issue with the PowerShell ConstrainedLanguage has been solved. When Applocker is in place a powershell script might be executed with a limited set of commands. So when the constrainedlanguage mode has been detected, the script falls back to a silent mode. Also, the user-detection part is not executed.
The examples below have been created on a Windows 10 English with a French MUI pack and with version 0.2:
Command line | Picture and logfile |
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" | ![]() |
<No logfile> | |
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging | ![]() |
jeu. 21 janv. 2021 18:55:57 ***** Check SCCM Client ***** jeu. 21 janv. 2021 18:55:57 ***** User details part ***** jeu. 21 janv. 2021 18:55:57 ***** Language part ***** jeu. 21 janv. 2021 18:55:57 Adding all the actions to the datagrid. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging -AllDefaultClientActions | ![]() |
jeu. 21 janv. 2021 18:59:25 ***** Check SCCM Client ***** jeu. 21 janv. 2021 18:59:25 ***** User details part ***** jeu. 21 janv. 2021 18:59:25 ***** Language part ***** jeu. 21 janv. 2021 18:59:25 Adding all the actions to the datagrid. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging -AllDefaultClientActions -Lock -NoCancel | ![]() |
jeu. 21 janv. 2021 19:01:44 ***** Check SCCM Client ***** jeu. 21 janv. 2021 19:01:44 ***** User details part ***** jeu. 21 janv. 2021 19:01:44 ***** Language part ***** jeu. 21 janv. 2021 19:01:44 The parameter -Lock is used, so the datagrid is locked for changes. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging -AllDefaultClientActions -Lock -NoCancel -LanguageOverride en | ![]() |
jeu. 21 janv. 2021 19:03:48 ***** Check SCCM Client ***** jeu. 21 janv. 2021 19:03:48 ***** User details part ***** jeu. 21 janv. 2021 19:03:48 ***** Language part ***** jeu. 21 janv. 2021 19:03:48 The parameter -Lock is used, so the datagrid is locked for changes. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging | ![]() |
jeu. 21 janv. 2021 19:06:43 ***** Check SCCM Client ***** jeu. 21 janv. 2021 19:06:43 ***** User details part ***** jeu. 21 janv. 2021 19:06:43 ***** Language part ***** jeu. 21 janv. 2021 19:06:43 Adding all the actions to the datagrid. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -DetailedLogging | ![]() |
jeu. 21 janv. 2021 19:14:56 ***** Check SCCM Client ***** jeu. 21 janv. 2021 19:14:57 ***** User details part ***** jeu. 21 janv. 2021 19:14:57 ***** Language part ***** jeu. 21 janv. 2021 19:14:57 Adding all the actions to the datagrid. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v01.ps1" -DetailedLogging -LanguageOverride en | ![]() |
mar. 19 janv 2021 20:08:32 ***** Check SCCM Client *****
mar. 19 janv 2021 20:08:32 The SCCM Client is not working fine or not installed at all. mar. 19 janv 2021 20:08:32 ***** User details part ***** mar. 19 janv 2021 20:08:32 ***** Language part ***** mar. 19 janv 2021 20:08:33 The SCCM Client is not working fine. So the error screen is shown. |
|
."C:\SCCMActions\PerformAllSCCMClientActions_v01.ps1" -DetailedLogging -Silent | ![]() |
mar. 19 janv. 2021 20:15:53 ***** Check SCCM Client *****
mar. 19 janv. 2021 20:15:53 The SCCM Client is working fine. mar. 19 janv. 2021 20:15:53 ***** User details part ***** mar. 19 janv. 2021 20:15:53 ***** Language part ***** mar. 19 janv. 2021 20:15:53 Running action: Software Metering Usage Report Cycle |
Script usage: Get-Help "C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1" -Detailed
NAME
C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1
SYNOPSIS
Perform all SCCM Client Actions.
SYNTAX
C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1 [-LanguageOverride <String>] [-DetailedLogging] [-NoCancel]
[-Silent] [-AllClientActions] [-Lock] [-HideSCCMClientButtons] [<CommonParameters>]
DESCRIPTION
Perform all SCCM Client Actions.
PARAMETERS
-LanguageOverride <String>
-DetailedLogging [<SwitchParameter>]
-NoCancel [<SwitchParameter>]
-Silent [<SwitchParameter>]
-AllClientActions [<SwitchParameter>]
-Lock [<SwitchParameter>]
-HideSCCMClientButtons [<SwitchParameter>]
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216).
-------------------------- EXAMPLE 1 --------------------------
PS C:\>Let the user select the actions you want to perform.
."PerformAllSCCMClientActions_v01.ps1"
-------------------------- EXAMPLE 2 --------------------------
PS C:\>Let the user select the actions you want to perform with verbose output.
."PerformAllSCCMClientActions_v02.ps1" -Verbose
-------------------------- EXAMPLE 3 --------------------------
PS C:\>Perform all the actions silent.
."PerformAllSCCMClientActions_v02.ps1" -Silent
-------------------------- EXAMPLE 4 --------------------------
PS C:\>Perform all the actions and suppress the Cancel button. Lock the window for changes.
Create a logfile in the users' %TEMP% folder.
."PerformAllSCCMClientActions_v02.ps1" -AllClientActions -NoCancel -Lock -DetailedLogging
-------------------------- EXAMPLE 5 --------------------------
PS C:\>Perform all the actions and suppress the Cancel button. Lock the window for changes. Force the German
language.
Create a logfile in the users' %TEMP% folder.
."PerformAllSCCMClientActions_v02.ps1" -AllClientActions -NoCancel -Lock -LanguageOverride de -DetailedLogging
-------------------------- EXAMPLE 6 --------------------------
PS C:\>Perform all the actions and suppress the Cancel button. Lock the window for changes. Force the German
language.
Create a logfile in the users' %TEMP% folder. Hide the SCCM Client buttons.
."PerformAllSCCMClientActions_v02.ps1" -AllClientActions -NoCancel -Lock -LanguageOverride de -DetailedLogging
-HideSCCMClientButtons
REMARKS
To see the examples, type: "get-help C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1 -examples".
For more information, type: "get-help C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1 -detailed".
For technical information, type: "get-help C:\SCCMActions\PerformAllSCCMClientActions_v02.ps1 -full".
And the script:
<#
.SYNOPSIS
Perform all SCCM Client Actions.
.DESCRIPTION
Perform all SCCM Client Actions.
.EXAMPLE
Let the user select the actions you want to perform.
."PerformAllSCCMClientActions_v04.ps1"
.EXAMPLE
Let the user select the actions you want to perform with verbose output.
."PerformAllSCCMClientActions_v04.ps1" -Verbose
.EXAMPLE
Perform all the actions silent.
."PerformAllSCCMClientActions_v04.ps1" -Silent
.EXAMPLE
Perform all the actions and suppress the Cancel button. Lock the window for changes.
Create a logfile in the users' %TEMP% folder.
."PerformAllSCCMClientActions_v04.ps1" -AllClientActions -NoCancel -Lock -DetailedLogging
.EXAMPLE
Perform all the actions and suppress the Cancel button. Lock the window for changes. Force the German language.
Create a logfile in the users' %TEMP% folder.
."PerformAllSCCMClientActions_v04.ps1" -AllClientActions -NoCancel -Lock -LanguageOverride de -DetailedLogging
.EXAMPLE
Perform all the actions and suppress the Cancel button. Lock the window for changes. Force the German language.
Create a logfile in the users' %TEMP% folder. Hide the SCCM Client buttons.
."PerformAllSCCMClientActions_v04.ps1" -AllClientActions -NoCancel -Lock -LanguageOverride de -DetailedLogging -HideSCCMClientButtons
.NOTES
Author: Willem-Jan Vroom
Website: https://www.vroom.cc/
Twitter: @TheStingPilot
v0.1:
* Initial version.
v0.2:
* Added two buttons:
- SCCM Client Properties
- SCCM Client Components
* The parameter 'HideSCCMClientButtons' has been introduced.
* The parameter 'AllDefaultClientActions' has been renamed to 'AllClientActions'.
v0.3:
* The json file has the same name as the script. Easier for versioning.
* The name of the logfile is written to to the screen when usering verbose mode.
v0.4:
* The PowerShell LanguageMode is detected. If running in ConstrainedMode than running in silent mode and
no use of forms.
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
Param
(
[Parameter(HelpMessage = 'Override the language.')]
[Parameter(Mandatory = $False, ParameterSetName = 'Default')]
[String] $LanguageOverride,
[Parameter(HelpMessage ='Logging to the logfile in the users %TEMP% folder.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $DetailedLogging,
[Parameter(HelpMessage ='Suppress the Cancel button.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $NoCancel,
[Parameter(HelpMessage ='Perform the operation silently.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $Silent,
[Parameter(HelpMessage ='Perform all the default client actions.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $AllClientActions,
[Parameter(HelpMessage ='Lock the datagrid, so no changes can be made.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $Lock,
[Parameter(HelpMessage ='Do not show the SCCM Client Properties and SCCM Client Components buttons.')]
[Parameter(Mandatory = $False, ParameterSetName='Default')]
[Switch] $HideSCCMClientButtons
)
# =============================================================================================================================================
# Function block
# =============================================================================================================================================
Function Add-EntryToLogFile
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 17-May-2020
Created by: Willem-Jan Vroom
Organization:
Functionname: Add-EntryToLogFile
=============================================================================================================================================
.SYNOPSIS
This function adds a line to a log file
#>
Param
(
[string] $Entry
)
Write-Verbose $Entry
if($Global:DetailedLogging)
{
$Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
Add-Content $Global:LogFile -Value $($Timestamp + " " + $Entry) -Force -ErrorAction SilentlyContinue
}
}
Function Test-RegistryKeyValue
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 30-Dec-20
Created by: (C) Aaron Jensen
https://stackoverflow.com/questions/5648931/test-if-registry-value-exists
Organization: Carbon Module
Functionname: Test-RegistryKeyValue
=============================================================================================================================================
.SYNOPSIS
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $Path,
[Parameter(Mandatory = $true)]
[string] $Name
)
if (-not (Test-Path -Path $Path -PathType Container))
{
return $false
}
$properties = Get-ItemProperty -Path $Path
if (-not $properties)
{
return $false
}
$member = Get-Member -InputObject $properties -Name $Name
if ($member)
{
return $true
}
else
{
return $false
}
}
Function UserDetails
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 03-Jan-21 / Modified on 14-Jan-21
Created by: Willem-Jan Vroom
Functionname: UserDetails
=============================================================================================================================================
.SYNOPSIS
This function returns 4 details of the Current Logged In Usser
1. The username of the current logged in user
2. User\Domain of the current logged in user
3. User SID fo the User\Domain
4. Account name that is using the script
#>
$Explorer = (Get-WMIObject -Query "Select * From Win32_Process Where Name='explorer.exe'")
if($Explorer.Count -gt 1)
{
$UserName = ($Explorer[-1]).GetOwner()
$SID = (($Explorer[-1]).GetOwnerSID()).SID
}
else
{
$UserName = ($Explorer).GetOwner()
$SID = (($Explorer).GetOwnerSID()).SID
}
$UserAndDomain = "$($Username.Domain )\$($Username.User)"
$ScriptAccount = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Return $($Username.User),$UserAndDomain,$SID,$ScriptAccount
}
Function Find-Language
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 30-Dec-20
Created by: Willem-Jan Vroom
Organisation:
Functionname: Find-Language
=============================================================================================================================================
.SYNOPSIS
#>
[CmdletBinding()]
Param
(
$CurrentUserSID
)
$Result = "en-US"
$RegKey = "REGISTRY::HKEY_USERS\$CurrentUserSID\Control Panel\Desktop"
$Value = "PreferredUILanguages"
if (Test-RegistryKeyValue -Path $RegKey -Name $Value)
{
$Result = (get-itemproperty $RegKey | Select -ExpandProperty $Value).Split()[0]
Add-EntryToLogFile -Entry "Regkey '$RegKey' value '$Value' exists. The data is '$Result'."
Return $Result
}
$RegKey = "REGISTRY::HKEY_USERS\.DEFAULT\Control Panel\Desktop\MuiCached"
$Value = "MachinePreferredUILanguages"
if (Test-RegistryKeyValue -Path $RegKey -Name $Value)
{
$Result = (get-itemproperty $RegKey | Select -ExpandProperty $Value).Split()[0]
Add-EntryToLogFile -Entry "Regkey '$RegKey' value '$Value' exists. The data is '$Result'."
Return $Result
}
Add-EntryToLogFile -Entry "There was a problem reading the registry..."
Return $Result
}
Function Check-SCCMClient
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 14-Jan-21
Created by: Willem-Jan Vroom
Organisation:
Functionname: Check-SCCMClient
=============================================================================================================================================
.SYNOPSIS
This function checks if the SCCM client on the machine is operational. It returns either nothing or an error message.
#>
$ErrorMessage = ""
Add-EntryToLogFile -Entry "***** Check SCCM Client *****"
Try
{
$class = Get-WmiObject -Class 'SMS_CLIENT' -List -Namespace 'root\ccm' -ErrorAction Stop
Add-EntryToLogFile -Entry "The SCCM Client is working fine."
Add-EntryToLogFile -Entry "***** End checking SCCM Client *****"
Return $True,$ErrorMessage
}
Catch
{
$ErrorMessage = $($_.Exception.Message).Trim()
Add-EntryToLogFile -Entry "The SCCM Client is not working fine or not installed at all."
Add-EntryToLogFile -Entry "The error message is: $ErrorMessage"
Add-EntryToLogFile -Entry "***** End checking SCCM Client *****"
Return $False,$ErrorMessage
}
}
Function SCCMClientProperties
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 20-Jan-21
Created by: Willem-Jan Vroom
Functionname: SCCMClientProperties
=============================================================================================================================================
.SYNOPSIS
This function shows a screen with the SCCM Client Properties or the SCCM Client Components.
#>
[CmdletBinding()]
param
(
[ValidateSet("Properties", "Components")]
[string] $Show,
[string] $Title
)
Add-EntryToLogFile -Entry "Clicked on the button '$Title'"
Add-EntryToLogFile -Entry "The SCCM Client $Show"
$frmSCCMClientDetails = New-Object 'System.Windows.Forms.Form'
$datagridview_Details = New-Object 'System.Windows.Forms.DataGridView'
$btnOk1 = New-Object 'System.Windows.Forms.Button'
$frmSCCMClientDetails.Controls.Add($datagridview_Details)
$frmSCCMClientDetails.Controls.Add($btnOk1)
$frmSCCMClientDetails.AcceptButton = $btnOk1
$frmSCCMClientDetails.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$frmSCCMClientDetails.AutoScaleMode = 'Font'
$frmSCCMClientDetails.ClientSize = New-Object System.Drawing.Size(430, 354)
$frmSCCMClientDetails.ControlBox = $False
$frmSCCMClientDetails.FormBorderStyle = 'Fixed3D'
$frmSCCMClientDetails.Name = 'frmSCCMClientDetails'
$frmSCCMClientDetails.StartPosition = 'CenterParent'
$frmSCCMClientDetails.Text = $Title
$datagridview_Details.ColumnHeadersHeightSizeMode = 'AutoSize'
$datagridview_Details.Location = New-Object System.Drawing.Point(13, 13)
$datagridview_Details.Name = 'datagridview_Details'
$datagridview_Details.Size = New-Object System.Drawing.Size(405, 298)
$datagridview_Details.TabIndex = 1
$datagridview_Details.ScrollBars = 'Both'
$datagridview_Details.ReadOnly = $True
$datagridview_Details.AllowUserToAddRows = $False
$datagridview_Details.AllowUserToDeleteRows = $False
$datagridview_Details.AllowUserToResizeColumns = $False
$datagridview_Details.AllowUserToResizeRows = $False
$datagridview_Details.MultiSelect = $False
$datagridview_Details.ReadOnly = $True
$datagridview_Details.ColumnCount = 2
$datagridview_Details.AllowUserToResizeColumns = $True
$btnOk1.Location = New-Object System.Drawing.Point(343, 317)
$btnOk1.Name = 'btnOk'
$btnOk1.Size = New-Object System.Drawing.Size(75, 25)
$btnOk1.TabIndex = 0
$btnOk1.Text = '&Ok'
$btnOk1.UseVisualStyleBackColor = $True
$btnOk1.add_Click({$frmSCCMClientDetails.Close()})
if($Show -eq "Properties")
{
$SCCMClientProperties = $Global:CPApplet.GetClientProperties() | Select-Object Name,Value
$datagridview_Details.Columns[0].Name = "Name"
$datagridview_Details.Columns[0].width = 150
$datagridview_Details.Columns[1].Name = "Value"
$datagridview_Details.Columns[1].width = 250
$SCCMClientProperties
ForEach ($Property in $SCCMClientProperties)
{
$PropertyName = $Property."Name"
$PropertyValue = $Property."Value"
if( ($PropertyName -eq "ClientVersion") -or ($PropertyName -eq "CurrentManagementPoint") -or ($PropertyName -eq "Name") )
{
$datagridview_Details.Rows.Add($PropertyName,$PropertyValue) | Out-Null
Add-EntryToLogFile -Entry "The SCCM Client property '$PropertyName' has the value '$PropertyValue'"
}
}
}
else
{
$SCCMClientComponents = $Global:CPApplet.GetClientComponents() | Select-Object DisplayName,Version
$datagridview_Details.Columns[0].Name = "Name"
$datagridview_Details.Columns[0].width = 240
$datagridview_Details.Columns[1].Name = "Version"
$datagridview_Details.Columns[1].width = 160
ForEach ($Component in $SCCMClientComponents)
{
$ComponentDisplayName = $Component."DisplayName"
$ComponentVersion = $Component."Version"
$datagridview_Details.Rows.Add($ComponentDisplayName,$ComponentVersion) | Out-Null
Add-EntryToLogFile -Entry "The SCCM Client Component '$ComponentDisplayName' has the version '$ComponentVersion'"
}
}
[void]$frmSCCMClientDetails.ShowDialog($formPerformSCCMClientAct)
Add-EntryToLogFile -Entry "End of the SCCM Client $Show"
}
# =============================================================================================================================================
# End function block
# =============================================================================================================================================
# =============================================================================================================================================
# Declares the variables.
# =============================================================================================================================================
Clear-Host
$CurrentDir = Split-Path -parent $MyInvocation.MyCommand.Definition
$arrAppNames = @()
$Global:DetailedLogging = $DetailedLogging
$ApplicationName = "Perform all SCCM Client Actions"
$ApplicationVersion = "v0.4"
$DefaultWaitInSeconds = 0.5
$Global:bolConstrainedLanguage = $ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage"
# =============================================================================================================================================
# Find the logpath.
# It is the key 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' with the value 'Local AppData'.
# And then '\temp' is added.
# =============================================================================================================================================
if($Global:bolConstrainedLanguage)
{
$LogPath = $Env:TEMP
$Silent = $True
}
else
{
$OnlyUserName, `
$LoggedOnUserInDomainFormat, `
$UseridSID, `
$InstallAccount = UserDetails
$RegKey = "REGISTRY::HKEY_USERS\$UseridSID\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
$ValueName = "Local AppData"
$Value = ((Get-ItemProperty $RegKey).$ValueName)
$LogPath = $Value + "\temp"
}
# =============================================================================================================================================
# Define the results file. This file contains all the results.
# =============================================================================================================================================
if($Global:DetailedLogging)
{
$strLastPartOfFileName = " ($((Get-Date).ToString('G'))).log"
$strLastPartOfFileName = $strLastPartOfFileName -replace ":","-"
$strLastPartOfFileName = $strLastPartOfFileName -replace "/","-"
$PreFixLogFile = "PerformAllSCCMClientActions"
$Global:LogFile = $LogPath + "\"+ $PreFixLogFile + $strLastPartOfFileName
New-Item $Global:LogFile -ItemType File -Force | Out-Null
Add-EntryToLogFile -Entry "The logfile '$($Global:LogFile)' has been created."
}
if($Global:bolConstrainedLanguage)
{
Add-EntryToLogFile -Entry "The logpath has been changed to '$LogPath' due to the PowerShell LanguageMode."
Add-EntryToLogFile -Entry "The script will run in a silent mode."
}
# =============================================================================================================================================
# Check if there is a (working) SCCM Client installed.
# =============================================================================================================================================
$BoleanSCCMClient,$ErrorMessageRegardingSCCMClient = Check-SCCMClient
# =============================================================================================================================================
# Find all the arguments and put them in the log file
# Source: https://ss64.com/ps/psboundparameters.html
# =============================================================================================================================================
if(-not($Global:bolConstrainedLanguage))
{
$TableWithParameters = @()
$RecordWithParameters = [ordered] @{"Key" = "";
"Value" = ""}
Add-EntryToLogFile -Entry "***** Parameters part *****"
ForEach($boundparam in $PSBoundParameters.GetEnumerator())
{
$tmpValue = $($boundparam.Value)
$Value = ""
if($tmpValue -is [array])
{
ForEach ($object in $tmpValue)
{
if(-not($value))
{
$Value = $object
}
else
{
$Value +=",$($object)"
}
}
}
else
{
$Value = $tmpValue
}
Add-EntryToLogFile -Entry "Key: $($boundparam.Key) Value: $Value"
}
Add-EntryToLogFile -Entry "***** End Parameters part *****`r`n"
}
else
{
Add-EntryToLogFile -Entry "The parameters are not written to the logfile due to PowerShell ConstrainedMode."
}
# =============================================================================================================================================
# Write the logged in user details to the log file.
# =============================================================================================================================================
if($Global:bolFullLanguage)
{
Add-EntryToLogFile -Entry "The userdetails are not written to the logfile due to the PowerShell ConstrainedMode."
}
else
{
Add-EntryToLogFile -Entry "***** User details part *****"
Add-EntryToLogFile -Entry "Logged on user: $LoggedOnUserInDomainFormat"
Add-EntryToLogFile -Entry "Logged on user (SID): $UseridSID"
Add-EntryToLogFile -Entry "Installation account: $InstallAccount"
Add-EntryToLogFile -Entry "***** End User details part *****`r`n"
}
# =============================================================================================================================================
# Read the JSON file with the translations.
# If the JSON file does not contain the detected language, then fallback to English.
# =============================================================================================================================================
if(-not($Global:bolConstrainedLanguage))
{
Add-EntryToLogFile -Entry "***** Language part *****"
if ($LanguageOverride)
{
$Language = $LanguageOverride
Add-EntryToLogFile "The parameter -LanguageOverride is used. The language is '$Language'."
}
else
{
$Language = (Find-Language -CurrentUserSID $UseridSID).SubString(0, 2)
}
$JSONFile = $CurrentDir + "\"+ $($MyInvocation.MyCommand.Name -replace ".ps1",".json")
if (-not (Test-Path $JSONFile))
{
$Message = "The language file '$JSONFile' does not exists. Leaving the script."
Add-EntryToLogFile -Entry $Message
Write-Host $Message
Exit 1
}
$SCCMActions = Get-Content $JSONFile -Encoding UTF8 | ConvertFrom-Json
if (-not ($SCCMActions.$Language))
{
Add-EntryToLogFile "The language '$Language' is not found in the json file '$JSONFile'."
$Language = "en"
Add-EntryToLogFile "Falling back to the default language '$Language'."
}
Add-EntryToLogFile "The language '$Language' is used."
Add-EntryToLogFile -Entry "***** End language part *****`r`n"
}
# =============================================================================================================================================
# End reading the JSON file with the translations.
# =============================================================================================================================================
if($Silent)
{
# =============================================================================================================================================
# Begin silent block
# =============================================================================================================================================
$AllClientActions = $True
if(-not ($BoleanSCCMClient))
{
$ErrorMessage = "There is no working SCCM Client."
Add-EntryToLogFile -Entry $ErrorMessage
Write-Host $ErrorMessage
Exit 2
}
# =============================================================================================================================================
# Perform the SCCM Client Actions
# =============================================================================================================================================
$Global:CPApplet = New-Object -Comobject CPApplet.CPAppletMgr
$Actions = $Global:CPApplet.GetClientActions()
$Counter = 1
$Total = $Actions.Count
ForEach ($Object in $Actions)
{
Write-Progress -Activity "Processing all the SCCM Client Actions" -Status "Action: $($Object.Name)." -PercentComplete (($Counter / $Total) * 100 )
Try
{
Add-EntryToLogFile -Entry "Running action: $($Object.Name)"
$Object.PerformAction()
}
Catch
{
$ErrorMessage = ($_.Exception.Message).Trim()
Add-EntryToLogFile -Entry "There was an error while running the SCCM Client Action '$($Object.Name)'."
Add-EntryToLogFile -Entry "Error message: $ErrorMessage."
}
Sleep -Seconds $DefaultWaitInSeconds
$Counter ++
}
# =============================================================================================================================================
# End silent block
# =============================================================================================================================================
}
Else
{
# =============================================================================================================================================
# Begin not silent block
# =============================================================================================================================================
# =============================================================================================================================================
# Forms Block
# =============================================================================================================================================
Add-Type -AssemblyName System.Windows.Forms
$formPerformSCCMClientAct = New-Object 'System.Windows.Forms.Form'
$btnCancel = New-Object 'System.Windows.Forms.Button'
$btnOk = New-Object 'System.Windows.Forms.Button'
$chkAllDefaultActions = New-Object 'System.Windows.Forms.CheckBox'
$txtActionName = New-Object 'System.Windows.Forms.TextBox'
$txtDescription = New-Object 'System.Windows.Forms.TextBox'
$DefaultSCCMActions = New-Object 'System.Windows.Forms.DataGridView'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
$SCCMActionsProgressBar = New-Object 'System.Windows.Forms.ProgressBar'
$btnClientComponents = New-Object 'System.Windows.Forms.Button'
$btnClientProperties = New-Object 'System.Windows.Forms.Button'
$formPerformSCCMClientAct_Shown={
# =============================================================================================================================================
# Check the SCCM Client and show a box in case the SCCM Client is not working at all.
# There is an error if the function 'Check-SCCMClient' returns not an empty string.
# =============================================================================================================================================
if (-not($BoleanSCCMClient))
{
Add-EntryToLogFile "The SCCM Client is not working fine. So the error screen is shown."
$frmSCCMClient = New-Object 'System.Windows.Forms.Form'
$txtNoSCCMClient = New-Object 'System.Windows.Forms.TextBox'
$btnOkErrorForm = New-Object 'System.Windows.Forms.Button'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
$btnOkErrorForm_Click={
$tmpValue = $($SCCMActions.$Language.btnOk).Replace("&","")
Add-EntryToLogFile -Entry "The '$tmpValue' button has been clicked."
Add-EntryToLogFile -Entry "The application is closed."
$frmSCCMClient.Close()
$frmSCCMClient.Dispose()}
$frmSCCMClient.Controls.Add($txtNoSCCMClient)
$frmSCCMClient.Controls.Add($btnOkErrorForm)
$frmSCCMClient.AcceptButton = $btnOkErrorForm
$frmSCCMClient.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$frmSCCMClient.AutoScaleMode = 'Font'
$frmSCCMClient.ClientSize = New-Object System.Drawing.Size(287, 106)
$frmSCCMClient.ControlBox = $False
$frmSCCMClient.FormBorderStyle = 'Fixed3D'
$frmSCCMClient.Name = 'frmSCCMClient'
$frmSCCMClient.Text = 'SCCM Client'
$frmSCCMClient.StartPosition = 'CenterScreen'
$txtNoSCCMClient.Location = New-Object System.Drawing.Point(13, 13)
$txtNoSCCMClient.Multiline = $True
$txtNoSCCMClient.Name = 'txtNoSCCMClient'
$txtNoSCCMClient.Size = New-Object System.Drawing.Size(259, 47)
$txtNoSCCMClient.TabIndex = 1
$txtNoSCCMClient.TabStop = $False
$txtNoSCCMClient.Text = "$($SCCMActions.$Language.txtNoSCCMClient) $ErrorMessageRegardingSCCMClient."
$btnOkErrorForm.Location = New-Object System.Drawing.Point(197, 66)
$btnOkErrorForm.Name = 'btnOkErrorForm'
$btnOkErrorForm.Size = New-Object System.Drawing.Size(75, 25)
$btnOkErrorForm.TabIndex = 0
$btnOkErrorForm.Text = $SCCMActions.$Language.btnOk
$btnOkErrorForm.UseVisualStyleBackColor = $True
$btnOkErrorForm.add_Click($btnOkErrorForm_Click)
$btnOk.Enabled = $False
$DefaultSCCMActions.Enabled = $False
$chkAllDefaultActions.Enabled = $False
$btnClientComponents.Enabled = $False
$btnClientProperties.Enabled = $False
$btnCancel.Enabled = $True
$btnCancel.Visible = $True
$frmSCCMClient.ShowDialog() | Out-Null
}
else
{
$chkAllDefaultActions.Checked = $AllClientActions
}
# =============================================================================================================================================
# End checking the SCCM Client.
# =============================================================================================================================================
}
$formPerformSCCMClientAct.Controls.Add($btnCancel)
$formPerformSCCMClientAct.Controls.Add($btnOk)
$formPerformSCCMClientAct.Controls.Add($chkAllDefaultActions)
$formPerformSCCMClientAct.Controls.Add($DefaultSCCMActions)
$formPerformSCCMClientAct.Controls.Add($SCCMActionsProgressBar)
$formPerformSCCMClientAct.Controls.Add($txtActionName)
$formPerformSCCMClientAct.Controls.Add($txtDescription)
$formPerformSCCMClientAct.Controls.Add($btnClientComponents)
$formPerformSCCMClientAct.Controls.Add($btnClientProperties)
$formPerformSCCMClientAct.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$formPerformSCCMClientAct.AutoScaleMode = 'Font'
$formPerformSCCMClientAct.ClientSize = New-Object System.Drawing.Size(467, 504)
$formPerformSCCMClientAct.Name = 'formPerformSCCMClientAct'
$formPerformSCCMClientAct.Text = "$ApplicationName $ApplicationVersion"
$formPerformSCCMClientAct.add_shown($formPerformSCCMClientAct_Shown)
$formPerformSCCMClientAct.FormBorderStyle = 'FixedDialog'
$formPerformSCCMClientAct.StartPosition = 'CenterScreen'
$btnClientProperties.Location = New-Object System.Drawing.Point(24, 449)
$btnClientProperties.Name = 'btnClientProperties'
$btnClientProperties.Size = New-Object System.Drawing.Size(110, 44)
$btnClientProperties.TabIndex = 10
$btnClientProperties.Text = $SCCMActions.$Language.SCCMClientProperties
$btnClientProperties.UseVisualStyleBackColor = $True
$btnClientProperties.add_Click({SCCMClientProperties -Show Properties -Title $($SCCMActions.$Language.SCCMClientProperties)})
$btnClientComponents.Location = New-Object System.Drawing.Point(140, 449)
$btnClientComponents.Name = 'btnClientComponents'
$btnClientComponents.Size = New-Object System.Drawing.Size(110, 44)
$btnClientComponents.TabIndex = 11
$btnClientComponents.Text = $SCCMActions.$Language.SCCMClientComponents
$btnClientComponents.UseVisualStyleBackColor = $True
$btnClientComponents.add_Click({SCCMClientProperties -Show Components -Title $($SCCMActions.$Language.SCCMClientComponents)})
$btnCancel.Location = New-Object System.Drawing.Point(287, 449)
$btnCancel.Name = 'btnCancel'
$btnCancel.Size = New-Object System.Drawing.Size(75, 44)
$btnCancel.TabIndex = 5
$btnCancel.Text = $SCCMActions.$Language.btnCancel
$btnCancel.UseVisualStyleBackColor = $True
$btnCancel.add_Click($btnCancel_Click)
$btnOk.Location = New-Object System.Drawing.Point(368, 449)
$btnOk.Name = 'btnOk'
$btnOk.Size = New-Object System.Drawing.Size(75, 44)
$btnOk.TabIndex = 6
$btnOk.Text = $SCCMActions.$Language.btnOk
$btnOk.UseVisualStyleBackColor = $True
$chkAllDefaultActions.Location = New-Object System.Drawing.Point(24, 21)
$chkAllDefaultActions.Name = 'chkAllDefaultActions'
$chkAllDefaultActions.Size = New-Object System.Drawing.Size(240, 24)
$chkAllDefaultActions.TabIndex = 1
$chkAllDefaultActions.Text = $SCCMActions.$Language.chkAllDefaultActions
$chkAllDefaultActions.UseVisualStyleBackColor = $True
$DefaultSCCMActions.ColumnHeadersHeightSizeMode = 'AutoSize'
$DefaultSCCMActions.Location = New-Object System.Drawing.Point(24, 51)
$DefaultSCCMActions.Name = 'DefaultSCCMActions'
$DefaultSCCMActions.Size = New-Object System.Drawing.Size(419, 306)
$DefaultSCCMActions.TabIndex = 0
$DefaultSCCMActions.ColumnCount = 2
$DefaultSCCMActions.ColumnHeadersVisible = $true
$DefaultSCCMActions.Columns[0].Name = "Name"
$DefaultSCCMActions.Columns[0].width = 600
$DefaultSCCMActions.ScrollBars = 'Vertical'
$DefaultSCCMActions.ReadOnly = $True
$DefaultSCCMActions.AllowUserToAddRows = $False
$DefaultSCCMActions.AllowUserToDeleteRows = $False
$DefaultSCCMActions.AllowUserToResizeColumns = $False
$DefaultSCCMActions.AllowUserToResizeRows = $False
$DefaultSCCMActions.SelectionMode = "FullRowSelect"
$DefaultSCCMActions.MultiSelect = $true
$DefaultSCCMActions.ReadOnly = $True
$txtActionName.Location = New-Object System.Drawing.Point(153, 377)
$txtActionName.Name = 'txtActionName'
$txtActionName.Size = New-Object System.Drawing.Size(290, 20)
$txtDescription.Location = New-Object System.Drawing.Point(24, 377)
$txtDescription.Name = 'txtDescription'
$txtDescription.Size = New-Object System.Drawing.Size(123, 20)
$txtDescription.Text = $SCCMActions.$Language.txtDescription
$SCCMActionsProgressBar.Location = New-Object System.Drawing.Point(24, 403)
$SCCMActionsProgressBar.Name = '$SCCMActionsProgressBar'
$SCCMActionsProgressBar.Size = New-Object System.Drawing.Size(419, 40)
$SCCMActionsProgressBar.Visible = $False
$SCCMActionsProgressBar.Style = 'Continuous'
if($HideSCCMClientButtons)
{
Add-EntryToLogFile "The parameter 'HideSCCMClientButtons' is specified, so the buttons '$($SCCMActions.$Language.SCCMClientProperties)' and"
Add-EntryToLogFile "'$($SCCMActions.$Language.SCCMClientComponents)' will be invisible."
$btnClientProperties.Visible = $False
$btnClientComponents.Visible = $False
}
# =============================================================================================================================================
# End Forms Block
# =============================================================================================================================================
# =============================================================================================================================================
# Hide the Cancel button in case the parameter 'NoCancel' is used.
# =============================================================================================================================================
if($NoCancel)
{
$btnCancel.Visible = $False
$formPerformSCCMClientAct.ControlBox = $False
$tmpValue = $SCCMActions.$Language."btnCancel".Replace("&","")
Add-EntryToLogFile -Entry "The parameter -NoCancel is used, so the cancel button '$tmpValue' is invisible."
}
if($Lock)
{
$DefaultSCCMActions.ReadOnly = $True
$chkAllDefaultActions.Enabled = $False
Add-EntryToLogFile -Entry "The parameter -Lock is used, so the datagrid is locked for changes."
}
# =============================================================================================================================================
# Fill the grid
# =============================================================================================================================================
if($BoleanSCCMClient)
{
Add-EntryToLogFile "Adding all the actions to the datagrid."
$Global:CPApplet = New-Object -Comobject CPApplet.CPAppletMgr
$Actions = $Global:CPApplet.GetClientActions()
$Actions | foreach {$DefaultSCCMActions.Rows.Add($_."Name") | Out-Null }
if($AllClientActions)
{
Add-EntryToLogFile "The parameter 'AllClientActions' is specified, so all the rows are selected."
}
}
# =============================================================================================================================================
# End Fill the grid
# =============================================================================================================================================
# =============================================================================================================================================
# Create the buttons and checkboxes
# =============================================================================================================================================
$chkAllDefaultActions.Add_CheckedChanged({
if($chkAllDefaultActions.Checked)
{
$DefaultSCCMActions.SelectAll()
}
else
{
$DefaultSCCMActions.ClearSelection()
}
})
$btnOk.add_Click({
$btnOk.Enabled = $False
$btnCancel.Enabled = $False
$btnClientComponents.Enabled = $False
$btnClientProperties.Enabled = $False
$tmpValue = $($SCCMActions.$Language.btnOk).Replace("&","")
Add-EntryToLogFile -Entry "The '$tmpValue' button has been clicked."
$Total = $DefaultSCCMActions.SelectedRows.Count
$Counter = 1
$SCCMActionsProgressBar.Visible = $True
$Rows = $DefaultSCCMActions.SelectedRows
ForEach ($Row in $Rows)
{
$SCCMActionsProgressBar.Value = $($Counter / $Total * 100)
$SCCMActionName = $DefaultSCCMActions.Rows[$Row.Index].Cells['Name'].Value
ForEach ($Object in $Actions)
{
if($Object.Name -eq $SCCMActionName)
{
Try
{
$txtActionName.Text = $SCCMActionName
Add-EntryToLogFile -Entry "Running action: $SCCMActionName"
$Object.PerformAction()
}
Catch
{
$ErrorMessage = ($_.Exception.Message).Trim()
Add-EntryToLogFile -Entry "There was an error while running the SCCM Client Action '$SCCMActionName'."
Add-EntryToLogFile -Entry "Error message: $ErrorMessage."
}
}
}
Sleep -Seconds $DefaultWaitInSeconds
$Counter++
}
Add-EntryToLogFile -Entry "The application is closed."
$formPerformSCCMClientAct.Close()
})
$btnCancel.add_Click({
$tmpValue = $($SCCMActions.$Language.btnCancel).Replace("&","")
Add-EntryToLogFile -Entry "The '$tmpValue' button has been clicked."
Add-EntryToLogFile -Entry "The application is closed."
$formPerformSCCMClientAct.Close()
})
# =============================================================================================================================================
# End creating the buttons and checkboxes.
# =============================================================================================================================================
[void]$formPerformSCCMClientAct.ShowDialog()
$formPerformSCCMClientAct.Dispose()
# =============================================================================================================================================
# End not silent block
# =============================================================================================================================================
}
# =============================================================================================================================================
# End application
# =============================================================================================================================================
The content of PerformAllSCCMClientActions_v04.json:
{
"en" :
{
"btnCancel" : "&Cancel" ,
"btnOk" : "&Ok",
"chkAllDefaultActions" : "Select all default actions",
"txtNoSCCMClient" : "The SCCM Client is nog working properly. The error message is:",
"txtDescription" : "Running action:",
"SCCMClientProperties" : "SCCM Client Properties",
"SCCMClientComponents" : "SCCM Client Components"
},
"de" :
{
"btnCancel" : "&Aufheben" ,
"btnOk" : "&Ok",
"chkAllDefaultActions" : "Wählen Sie alle Standardaktionen aus",
"txtNoSCCMClient" : "Der SCCM-Client funktioniert nicht ordnungsgemäß. Die Fehlermeldung lautet:",
"txtDescription" : "Laufende Aktion:",
"SCCMClientProperties" : "SCCM-Client-Eigenschaften",
"SCCMClientComponents" : "SCCM-Client-Komponenten"
},
"nl" :
{
"btnCancel" : "&Annuleren" ,
"btnOk" : "&Ok",
"chkAllDefaultActions" : "Kies de volgende standaard client akties",
"txtNoSCCMClient" : "De SCCM client werkt niet goed. De foutmelding is:",
"txtDescription" : "Huidige aktie:",
"SCCMClientProperties" : "Eigenschappen SCCM Client",
"SCCMClientComponents" : "SCCM Client Componenten"
},
"es" :
{
"btnCancel" : "&Cancelar" ,
"btnOk" : "&Ok",
"chkAllDefaultActions" : "Seleccionar todas las acciones predeterminadas",
"txtNoSCCMClient" : "El cliente SCCM no funciona correctamente. El mensaje de error es:",
"txtDescription" : "Acción en ejecución:",
"SCCMClientProperties" : "Propiedades del cliente SCCM",
"SCCMClientComponents" : "Componentes del cliente SCCM"
},
"fr" :
{
"btnCancel" : "&Annuler" ,
"btnOk" : "&Ok",
"chkAllDefaultActions" : "Sélectionnez toutes les actions par défaut",
"txtNoSCCMClient" : "Le client SCCM ne fonctionne pas correctement. Le message d'erreur est:",
"txtDescription" : "Action en cours:",
"SCCMClientProperties" : "Propriétés du client SCCM",
"SCCMClientComponents" : "Composants du client SCCM"
}
}