Powershell – ERROR: Invalid syntax. Default option is not allowed more than ‘2’ time(s)

powershell

I'm trying to run the powershell script below to identify the USB or SCSI interfacetype connected to the computer, the script works just fine if I don't use the IF and -Or operators

if(($diskdrive = (gwmi win32_diskdrive | ?{$_.interfacetype -eq 'USB'})) -Or ($diskdrive =(gwmi win32_diskdrive | ?{$_.interfacetype -eq 'SCSI'}))){
$letters = $diskdrive | %{gwmi -Query "ASSOCIATORS OF 
{Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE

AssocClass = Win32_DiskDriveToDiskPartition"} |  %{gwmi -Query "ASSOCIATORS

OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass =

Win32_LogicalDiskToPartition"} | %{$_.Deviceid}
setx OSDUSBDrive $letters /M 
Write-Output $diskdrive, $letters}
Start-Sleep -s 5


    if (-not ("Win32.NativeMethods" -as [Type]))
    {
        # import sendmessagetimeout from win32
    Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessageTimeout(
        IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
        uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
    }

    $HWND_BROADCAST = [IntPtr] 0xffff;
    $WM_SETTINGCHANGE = 0x1a;
    $result = [UIntPtr]::Zero

    # notify all windows of environment block change
    [Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 5000, [ref] $result);

Start-Sleep -s 5

ERROR: Invalid syntax. Default option is not allowed more than '2'
time(s). C:\temp\AddOSDUSBDrive_NEW.ps1:10 : 1
+ setx OSDUSBDrive $letters /M
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Erreurÿ: Syntax…plus de 2 fois.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError Entrez "SETX /?" pour afficher la syntaxe.

Any idea?

Best Answer

Use setx OSDUSBDrive "$letters" /M

Applied SETX.exe syntax pattern

SETX [/s Computer [Credentials]] Variable Value [/m]
                                          ↑↑↑↑↑

could be wrong if $letters contains more letters e.g. F:, G:, H:

 setx OSDUSBDrive $letters /M
 #                ↑↑↑↑↑↑↑↑        this evaluates to
 setx OSDUSBDrive F: G: H: /M
 #                ↑↑ ↑↑ ↑↑        three space-separated values (WRONG)

Adjusted (see Syntax : Escape Characters, Delimiters and Quotes):

 setx OSDUSBDrive "$letters" /M
 #                ↑↑↑↑↑↑↑↑↑↑       this evaluates to
 setx OSDUSBDrive "F: G: H:" /M
 #                 ↑↑↑↑↑↑↑↑        one string value (quotes = escape characters)

Moreover, I'd adjust the first IF as follows:

if ( $diskdrive = ( Get-WmiObject win32_diskdrive | 
        Where-Object { $_.interfacetype -in ('USB','SCSI') } ) ) {

Explanation: -or operator means logical OR: TRUE when either i.e. if first operand evaluates to TRUE, then other operands are never evaluated.

For instance, run

Remove-Variable a, b -ErrorAction SilentlyContinue
if ( ($a = 1) -or ($b = 3) ) { Write-host "a=$a b=$b" }

The variable '$b' cannot be retrieved because it has not been set.

if ( ($a = $null) -or ($b = 3) ) { Write-host "a=$a b=$b" }

a= b=3