SCCM日志解析脚本动态参数ValidateSet及-log参数显示问题
Hey there! Let's work through those frustrating dynamic parameter issues with your SCCM log parsing script. I’ve run into these exact problems before, so let’s break down each fix step by step.
Fix 1: Get the Dynamic ValidateSet to Show Optional Values
The key here is ensuring your dynamic parameter block correctly generates the ValidateSet based on the user’s input for ComputerName and DiskPath. PowerShell only generates dynamic parameters after the mandatory "static" parameters are provided, so we need to build the log file list inside the dynamicparam block, and handle cases where the path might not exist to avoid crashes.
Here’s a revised version of your function with proper dynamic parameter setup:
function Get-SCCMLog { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$ComputerName, [Parameter(Mandatory=$true)] [string]$DiskPath ) # Dynamic parameter definition for -Log dynamicparam { $paramDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary # Build the full UNC path to SCCM logs $logUNCPath = "\\$ComputerName\$DiskPath`$\CCM\Logs" # Safely get log files (handle missing paths to avoid exceptions) $logFiles = if (Test-Path -Path $logUNCPath -ErrorAction SilentlyContinue) { Get-ChildItem -Path $logUNCPath -Filter "*.log" | Select-Object -ExpandProperty Name } else { @() # Empty array if path is unreachable/missing } # Create parameter attributes for -Log $logParamAttr = New-Object System.Management.Automation.ParameterAttribute $logParamAttr.Mandatory = $true $logParamAttr.HelpMessage = "Select the SCCM log file to parse" # Add ValidateSet with our log file list $validateSetAttr = New-Object System.Management.Automation.ValidateSetAttribute($logFiles) # Combine attributes into a collection $attrCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $attrCollection.Add($logParamAttr) $attrCollection.Add($validateSetAttr) # Create the dynamic parameter and add it to the dictionary $logParam = New-Object System.Management.Automation.RuntimeDefinedParameter("Log", [string], $attrCollection) $paramDict.Add("Log", $logParam) return $paramDict } # Bind the dynamic -Log parameter to a usable variable begin { $Log = $PSBoundParameters["Log"] } process { # Your log parsing logic here $fullLogPath = "\\$ComputerName\$DiskPath`$\CCM\Logs\$Log" Write-Verbose "Starting parse of $fullLogPath" # Add your SCCM log parsing code (like converting .log to readable format) } }
The critical bits here:
- We check if the log path exists inside the dynamicparam block so we only generate valid log file options when possible.
- We return an empty array if the path is missing, which prevents a null reference exception and tells PowerShell there are no valid options (instead of crashing).
- We bind the dynamic
$Logparameter in thebeginblock so it’s accessible in theprocessblock.
Fix 2: Make the -Log Parameter Visible When Calling the Function
Dynamic parameters don’t show up in tab completion or parameter lists until the required static parameters (ComputerName and DiskPath) are provided. Here’s how to get it to appear:
- First, enter the static parameters:
Get-SCCMLog -ComputerName "MY-SCCM-PC" -DiskPath "C" - Now, type
-Logand press Tab—you’ll see the list of valid log files populate.
If you’re using PowerShell ISE or VS Code, you might need to trigger parameter completion after entering the static parameters (usually by pressing Ctrl+Space or just typing -L and hitting Tab).
Fix 3: Eliminate First-Run Exceptions
First-run crashes typically happen when the UNC path is unreachable (wrong computer name, disk path, or network issue). To fix this:
- Add validation to the static parameters to catch bad inputs early:
[Parameter(Mandatory=$true)] [ValidateScript({ if (-not (Test-Connection -ComputerName $_ -Count 1 -Quiet -ErrorAction SilentlyContinue)) { throw "Computer $_ is not reachable. Check the name or network connection." } $true })] [string]$ComputerName, [Parameter(Mandatory=$true)] [ValidateScript({ $diskShare = "\\$ComputerName\$($_)`$" if (-not (Test-Path -Path $diskShare -ErrorAction SilentlyContinue)) { throw "Disk share $diskShare does not exist. Verify the disk path." } $true })] [string]$DiskPath
This way, the function will throw a clear error before even trying to generate dynamic parameters, instead of failing silently or crashing.
2. We already added the empty array fallback in the dynamicparam block, which prevents null reference errors if the log path is missing even after passing the initial validation.
Quick Recap
- Dynamic parameters depend on static parameters being provided first—so
-Logwon’t show up until you’ve enteredComputerNameandDiskPath. - Always handle missing/unreachable paths in the
dynamicparamblock to avoid exceptions. - Bind dynamic parameters in the
beginblock to use them in your parsing logic.
内容的提问来源于stack exchange,提问作者Thom Schumacher

