
Estoy intentando ejecutar el siguiente script de PowerShell para identificar el tipo de interfaz USB o SCSI conectado a la computadora. El script funciona bien si no uso los operadores IF
y-Or
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: Sintaxis no válida. La opción predeterminada no está permitida más de "2" veces. C:\temp\AddOSDUSBDrive_NEW.ps1:10: 1 + setx OSDUSBDrive $letras /M + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (Erreurÿ: Sintaxis...más de 2 hojas.:String) [], RemoteException + FullyQualifiedErrorId: NativeCommandError Ingrese "SETX /?" Para mostrar la sintaxis.
¿Alguna idea?
Respuesta1
Usarsetx OSDUSBDrive "$letters" /M
AplicadoSETX.exe
sintaxispatrón
SETX [/s Computer [Credentials]] Variable Value [/m] ↑↑↑↑↑
podría estar equivocado si $letters
contiene másletrasp.ej F:
, G:
,H:
setx OSDUSBDrive $letters /M
# ↑↑↑↑↑↑↑↑ this evaluates to
setx OSDUSBDrive F: G: H: /M
# ↑↑ ↑↑ ↑↑ three space-separated values (WRONG)
Ajustado (verSintaxis: caracteres de escape, delimitadores y comillas):
setx OSDUSBDrive "$letters" /M
# ↑↑↑↑↑↑↑↑↑↑ this evaluates to
setx OSDUSBDrive "F: G: H:" /M
# ↑↑↑↑↑↑↑↑ one string value (quotes = escape characters)
Además, ajustaría el primero IF
de la siguiente manera:
if ( $diskdrive = ( Get-WmiObject win32_diskdrive |
Where-Object { $_.interfacetype -in ('USB','SCSI') } ) ) {
Explicación: -or
operador significa lógico O:TRUE
cuando cualquieraes decir, si el primer operando se evalúa como TRUE
, los demás operandos nunca se evalúan.
Por ejemplo, ejecutar
Remove-Variable a, b -ErrorAction SilentlyContinue
if ( ($a = 1) -or ($b = 3) ) { Write-host "a=$a b=$b" }
La variable '$b' no se puede recuperar porque no se ha configurado.
if ( ($a = $null) -or ($b = 3) ) { Write-host "a=$a b=$b" }
a=b=3
Respuesta2
De hecho, agregué esto como sugeriste:
if ($diskdrive = ( Get-WmiObject win32_diskdrive | Where-Object { $_.interfacetype -in ('USB','SCSI') } ) ) {
el script funciona bien cuando lo ejecuto manualmente, sin embargo, aparece el siguiente error cuando lo invoco desde SCCM
Debe proporcionar una expresión de valor en el lado derecho del operador '-'. TaskSequencePSHost 6/03/2018 4:36:37 PM 0 (0x0000) En D:\SMS\PKG\SE1001B5\AddOSDUSBDrive_NEW.ps1:2 char:42 + Where-Object { $_.interfacetype - <<<< in ( 'USB','SCSI') } ) ){ TaskSequencePSHost 6/3/2018 4:36:37 p.m. 0 (0x0000) ParserError: (:) [], ParseException TaskSequencePSHost 6/03/2018 4:36:37 p.m. 0 (0x0000) TSHOST: Script completado con código de retorno 0 TaskSequencePSHost 6/03/2018 4:36:37 p. m. 0 (0x0000)