powershell

How To Pass a DeviceID with curly brackets as an argument


I am trying to pass a DeviceID into my Powershell script, but it keeps returning as a null value.

The device ID is: {0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435}

When I pass it this way using my script: powershell.exe .\SwitchWindowsAudio.ps1 {0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435} it will say that I have no arguments.

If I encapsulate the device ID using single quotes or double quotes it detects an argument, but I cannot print it to the screen as a script, nor can I utilize it. If I try to run .GetType() or anything against it the program returns that it is a "null-valued expression".

If I run AudioDeviceCmdlets' Get-AudioDevice -ID $args[0] using it, then it does not return a device. I am assuming that the curly brackets are doing something evil to the arguments list. Anyone have any experience with this or know how to pass it correctly?

NOTE: I have also tried escape characters at each curly bracket to no success. This is driving me loopy!

# Include Audio DLL
try {
    Import-Module AudioDeviceCmdlets
}
catch {
    Install-Module -Name AudioDeviceCmdlets
}

# Troubleshooting Area ----------
Write-Host($args[0].GetType())

Write-Host($deviceID)
Write-Host("Arguments passed: " + $args.Count.ToString())
# -------------------------------

# Verify Device ID was passed.
if ($args.Count -lt 1) {
    Write-Host("Not enough arguments were supplied to continue.")
    Write-Host("Example: powershell.exe .\SwitchWindowsAudio.ps1 {0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435}")
    exit 1
}

if ($args.Count -gt 1) {
    Write-Host("Only one argument should be supplied.")
    Write-Host("Example: powershell.exe .\SwitchWindowsAudio.ps1 {0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435}")
    exit 2
}

# Check if valid ID was provided.
try {
    $device = Get-AudioDevice -ID $args[0]
}
catch {
    Write-Host("A valid device ID was not provided.")
    Write-Host("Please check your device ID and try again.")
    exit 3
}

# Set Audio Device
Set-AudioDevice -ID $args[0]

Solution

  • Happens mainly on powershell.exe, you should use the -File or -f parameter if you're targeting a script and want to pass-in arguments:

    powershell -f .\SwitchWindowsAudio.ps1 '{0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435}'
    

    Another alternative that should also work would be (no -f needed here):

    powershell ".\SwitchWindowsAudio.ps1 '{0.0.0.00000000}.{44c76b90-01ce-485c-8705-e93f9be4c435}'"
    

    In pwsh.exe (PowerShell 7+) you don't need to specify -f (it's the default parameter there), however in all cases you must quote your argument, this is because { ... } is the syntax for a script block and since you have a dot right after {0.0.0.00000000} it will try to reference a property on the script block ({44c76b90-01ce-485c-8705-e93f9be4c435}) that doesn't exist, thus resulting to $null.