
Ich versuche, das folgende Powershell-Skript auszuführen, um den an den Computer angeschlossenen USB- oder SCSI-Schnittstellentyp zu identifizieren. Das Skript funktioniert einwandfrei, wenn ich die Operatoren IF
und nicht verwende.-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
FEHLER: Ungültige Syntax. Die Standardoption ist nicht öfter als „2“ Mal zulässig. C:\temp\AddOSDUSBDrive_NEW.ps1:10 : 1 + setx OSDUSBDrive $letters /M + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (Fehler: Syntax… mehr als 2 Mal:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError Geben Sie „SETX /?“ ein, um die Syntax anzuzeigen.
Irgendeine Idee?
Antwort1
Verwendensetx OSDUSBDrive "$letters" /M
AngewandtSETX.exe
SyntaxMuster
SETX [/s Computer [Credentials]] Variable Value [/m] ↑↑↑↑↑
könnte falsch sein, wenn $letters
mehr enthalten istBriefez.B F:
, G:
,H:
setx OSDUSBDrive $letters /M
# ↑↑↑↑↑↑↑↑ this evaluates to
setx OSDUSBDrive F: G: H: /M
# ↑↑ ↑↑ ↑↑ three space-separated values (WRONG)
Angepasst (sieheSyntax: Escape-Zeichen, Trennzeichen und Anführungszeichen):
setx OSDUSBDrive "$letters" /M
# ↑↑↑↑↑↑↑↑↑↑ this evaluates to
setx OSDUSBDrive "F: G: H:" /M
# ↑↑↑↑↑↑↑↑ one string value (quotes = escape characters)
Darüber hinausIF
, ich würde das erste wie folgt anpassen :
if ( $diskdrive = ( Get-WmiObject win32_diskdrive |
Where-Object { $_.interfacetype -in ('USB','SCSI') } ) ) {
Erläuterung: -or
Operator bedeutet logisches ODER:TRUE
wenn entwederd. h. wenn der erste Operand als ausgewertet wird TRUE
, werden die anderen Operanden nie ausgewertet.
Führen Sie beispielsweise
Remove-Variable a, b -ErrorAction SilentlyContinue
if ( ($a = 1) -or ($b = 3) ) { Write-host "a=$a b=$b" }
Die Variable „$b“ kann nicht abgerufen werden, da sie nicht festgelegt wurde.
if ( ($a = $null) -or ($b = 3) ) { Write-host "a=$a b=$b" }
a = b = 3
Antwort2
Ich habe tatsächlich Folgendes hinzugefügt, wie Sie vorgeschlagen haben:
wenn ( $diskdrive = ( Get-WmiObject win32_diskdrive | Where-Object { $_.interfacetype -in ('USB','SCSI') } ) ) {
Das Skript funktioniert einwandfrei, wenn ich es manuell ausführe. Wenn es jedoch von SCCM aufgerufen wird, erhalte ich den folgenden Fehler.
Sie müssen einen Wertausdruck auf der rechten Seite des Operators „-“ angeben. TaskSequencePSHost 06.03.2018 16:36:37 0 (0x0000) Bei D:\SMS\PKG\SE1001B5\AddOSDUSBDrive_NEW.ps1:2 char:42 + Where-Object { $_.interfacetype - <<<< in ('USB','SCSI') } ) ){ TaskSequencePSHost 06.03.2018 16:36:37 0 (0x0000) ParserError: (:) [], ParseException TaskSequencePSHost 06.03.2018 16:36:37 0 (0x0000) TSHOST: Skript mit Rückgabecode 0 abgeschlossen TaskSequencePSHost 06.03.2018 16:36:37 0 (0x0000)