Is this the correct usage of a switch command ?
So below is part of testing, but the full script will evaluate if the input is either a UUID number or a MACaddress, then pass the result to import a machine with the number passed. The command requires either a -SmBiosGuid or -MACAddress.
$Identifer = "F8:16:54:C1:83:33"
$UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
$MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
Switch ($Identifer) {
{$Identifer -match $UUID} { "UUID" }
{$Identifer -match $MAC} { "MACAddress" }
}
I’m thinking an ElseIf is the better solution :
function add-machine
{
[CmdletBinding()]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipeline=$True,
HelpMessage="Computer Name then either MACAddress or UUID (SmBiosGuid)")]
[string[]]$ComputerName,
[string[]]$Identifer,
[string]$ErrorLog = 'c:\temp\AddDeviceError.txt'
)
Begin
{
#Import Configuration Manager module
$ModulePath = $env:SMS_ADMIN_UI_PATH.Replace("i386","ConfigurationManager.psd1")
Import-Module $ModulePath
}
Process
{
[regex]$MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
[regex]$UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
if ($Identifier -match $MAC)
{ Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -MacAddress $Identifier }
elseif ($Identifier -match $UUID)
{ Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -SmBiosGuid $Identifier }
else
{Write-Warning "Not a valid MAC Address or SmBiosGuid"}
}
#Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -SmBiosGuid
}
End
{
}
Your example is basically attempting to match and if it matches then you can identify the identifier passed. See the example code below for switch and validateset implementations:
function Test-ValidateSet {
param (
[ValidateSet("MAC", "UUID")]
[string]$IdentifierType,
[string]$Identifier
)
switch ($IdentityType) {
"MAC" {$Pattern = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"}
"UUID"{ $Pattern = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" }
}
if ($Identifier -match $Pattern) {
}
else {
"Bad identifier"
}
}
function Test-Switch {
param (
[string]$Identifier,
[switch]$IsUUID
)
#Default pattern is MAC, so if you wanted to pass a UUID you'd have to specify the IsUUID switch
$Pattern = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$" }
if ($IsUUID) {$Pattern = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" }
if ($Identifier -match $Pattern) {
}
else {
"Bad identifier"
}
}
Rob, brilliant. Funny, now i look at what you have done looks logical. Not used the ValidateSet yet, useful to know. Learn’t a bit more today, so many thanks.
Rob, with the test-validate, do i pass the MAC or UUID to the Identifer ?
Graham, your way works, but you would typically structure it something like this.
$Identifer = "F8:16:54:C1:83:33"
#$Identifer = "d75e6376-7133-11e5-9d70-feff819cdc9f"
$UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
$MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
Switch -regex ($Identifer) {
$UUID { "UUID" }
$MAC { "MACAddress" }
}
or if you did not want to use variables
$Identifer = "F8:16:54:C1:83:33"
#$Identifer = "d75e6376-7133-11e5-9d70-feff819cdc9f"
Switch -regex ($Identifer) {
"^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" { "UUID" }
"^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$" { "MACAddress" }
}
Great examples above. Here’s how I’d handle it.
Function Test-Function {
[CmdletBinding(SupportsShouldProcess=$true,
ConfirmImpact='Medium')]
Param (
# Specifies the UUID or MAC Address
[Parameter(Mandatory=$true)]
[System.String]
[ValidateScript({($_ -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") -or ($_ -match "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$")})]
[System.String]
$Identifer
)
If ($Identifer -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") {
# MAC Address was entered
"MAC Address"
}
Else {
# UUID was entered
"UUID"
}
}
Then some test code
Test-Function -Identifer 20:58:9D:17:EF:52
Test-Function -Identifer f6f94322-7138-11e5-9d70-feff819cdc9f
Test-Function -Identifer Nonsense
Curtis and Scriptimus thank, both excellent solution. Fascinated by yours Scriptimus. Thank you !
My “Catch” doesn’t seem to work if the regex is not met…
Function Test-Function {
[CmdletBinding(SupportsShouldProcess=$true,
ConfirmImpact='Medium')]
Param (
# Specifies the UUID or MAC Address
[Parameter(Mandatory=$true)]
[System.String]
[ValidateScript({($_ -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") -or ($_ -match "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$")})]
[System.String]
$Identifer
)
try {
If ($Identifer -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") {
# MAC Address was entered
write-output "MAC Address" -ea STOP
}
Else {
# UUID was entered
write-output "UUID" -ea STOP
}
}
catch {
{
#No Return
write-warning $($_.Exception.Message)
}
}
}
The design here is that the Validate script will not allow the function to get past the parameter section if the regex is not matched.
As for the try/catch. This would typically go inside the If/Else scriptblocks but only if you wanted to handle something that could catastrophically fail.
In this situation you’re not doing anything except returning a string. The If/Else is sufficient.
To eliminate confusion further instead of write-output “UUID” as you used above, in the final code you could use
return ‘UUID’
Scriptimus Prime, why you do test for $Identifier twice ?
your code
“# UUID was entered
write-output “UUID” -ea STOP”
with this design can’t be executed at all because the ValidateScript disallow it
Yes Max, I gave that some thought.
The validate script seemed to be the more PowerShell way to start the script.
However, from then I couldn’t find a way to identify what was passed without testing again.
if the reduction of iterations was an objective, then perhaps it would be better to use switch or If, ElseIf, Else.