PowerShell Laufwerksbuchstaben tauschen

Arvyr

Cadet 4th Year
Registriert
Sep. 2018
Beiträge
74
Hallo,


ich möchte via PowerShell in einer VM die Laufwerksbuchstaben des CD/DVD-Rom Laufwerkes (D:) mit dem der zweiten Festplatte (E:) tauschen (ich mag einfach eine gewisse Ordnung, sonst gibt es keinen anderen Grund).

Leider funktioniert der Tausch nicht wie er soll, da beim Wechseln der Buchstaben irgendwas schief läuft.

Was ich bisher versucht habe:

PowerShell:
$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'D:'"
$Drive | Set-CimInstance -Property @{DriveLetter ='X:'}

$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'E:'"
$Drive | Set-CimInstance -Property @{DriveLetter ='D:'}

$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'X:'"
$Drive | Set-CimInstance -Property @{DriveLetter ='E:'}

Der erste Schritt läuft auch sauber durch, danach scheint das Skript zu hängen.
Ich habe es auch mit Pausen in Form von "Start-Sleep" versucht, da das Ändern des Laufwerksbuchstabens ja normalerweise einen Moment dauert - leider ohne Erfolg.

Absurderweise sorgt das Ganze aktuell dafür, dass ich, wenn das Skript beendet wurde, ein CD/DVD-Laufwerk mit Buchstaben X und die zweite Festplatte sowohl einmal mit E als auch mit D sehe.

Fehlermeldung:
PowerShell:
Set-CimInstance : Nicht verfügbar
In Zeile:10 Zeichen:10
+ $Drive | Set-CimInstance -Property @{DriveLetter ='E:'}
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Win32_Volume: X...b-a0f4-806e...):CimInstance) [Set-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80041009,Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

Vielleicht hat jemand schon mal so ein Problem gehabt und kennt eine Elegante Lösung für mein Problem.
 
Hier mal reingeschaut: https://docs.microsoft.com/en-us/powershell/module/cimcmdlets/set-ciminstance?view=powershell-7.1

Wenn ich die Beispiele sehe kannst du folgendes versuchen:


PowerShell:
Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'D:'"| Set-CimInstance -Property @{DriveLetter ='X:'}

Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'E:'"| Set-CimInstance -Property @{DriveLetter ='D:'}

Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'X:'"| Set-CimInstance -Property @{DriveLetter ='E:'}
auch wenn das (theoretisch) genau identisch sein sollte zu deinem Code, nur anders aufgeschrieben

Oder vielleicht

PowerShell:
$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'D:'"
Set-CimInstance -InputObject $Drive -Property @{DriveLetter ='X:'} -PassThru

$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'E:'"
Set-CimInstance -InputObject $Drive -Property @{DriveLetter ='D:'} -PassThru

$Drive = Get-CimInstance -ClassName Win32_Volume -Filter "DriveLetter = 'X:'"
Set-CimInstance -InputObject $Drive -Property @{DriveLetter ='E:'} -PassThru
 
Mh, nein.
Leider komme ich damit zum selben Ergebnis.
Es scheint irgendwie so zu sein, dass der freigewordene Buchstabe für eine Neuvergabe nicht verfügbar ist.
Warum das jedoch so ist, konnte ich noch nicht herausfinden.
 
Ich habe es grade nachzustellen versucht und hatte keine Probleme mit deinem Original-Skript

Testumgebung war eine Server 2019 VM mit zwei 1GB großen vhdx die ich für den Test erstellt und angehängt hatte, Laufwerksbuchstaben D: und E:
Das Skript wurde copy-paste übernommen und ist mehrfach erfolgreich durchgelaufen

Danach hatte ich eins der beiden Laufwerke gegen dein DVD-Laufwerk ausgetauscht und dasselbe nochmal versucht - auch keine Probleme.

Daher - sorry, aber keine Ahnung wo das Problem ist

Du könntest eine try-catch Struktur machen und vielleicht so ein Error-Output bekommen oder zumindest feststellen bei welchem Schritt dein Skript versagt? Ich bin mir jetzt unklar ob das der zweite oder dritte ist der anscheinend fehlschlägt

Eventuell kommt dir etwas in die Quere, das noch einen offenen Zugriff auf eins der Laufwerke hat?
 
Rickmer schrieb:
Ich habe es grade nachzustellen versucht und hatte keine Probleme mit deinem Original-Skript

Testumgebung war eine Server 2019 VM mit zwei 1GB großen vhdx die ich für den Test erstellt und angehängt hatte, Laufwerksbuchstaben D: und E:
Das Skript wurde copy-paste übernommen und ist mehrfach erfolgreich durchgelaufen

Danach hatte ich eins der beiden Laufwerke gegen dein DVD-Laufwerk ausgetauscht und dasselbe nochmal versucht - auch keine Probleme.

Daher - sorry, aber keine Ahnung wo das Problem ist

Du könntest eine try-catch Struktur machen und vielleicht so ein Error-Output bekommen oder zumindest feststellen bei welchem Schritt dein Skript versagt? Ich bin mir jetzt unklar ob das der zweite oder dritte ist der anscheinend fehlschlägt

Eventuell kommt dir etwas in die Quere, das noch einen offenen Zugriff auf eins der Laufwerke hat?

Bei mir ist es eine Windows Server 2019 Datacenter Eval VM auf VMware Workstation 16.
C: ist eine 50GB Partition, D: das optische Laufwerk und E: eine weitere Platte mit ca. 5GB.

Fehlermeldung kann ich dir versuchen mal nachzureichen.
Ergänzung ()

Tornhoof schrieb:
Sicher dass deine Befehle so gehen?
Nur weil du den Buchstaben entfernst, sind nicht notwendigerweise alle Handles auf dem device weg.
Mal mit mountvol probiert?
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mountvol

mountvol hatte ich auch schon in Teilen probiert.
Ich werde mir das noch mal genauer ansehen.
Ergänzung ()

Interessanterweise wirft mir die Error-Variable u.a. folgendes aus:

PowerShell:
CIMStatusCode             : 2147763456
CIMStatusCodeDescription  : Der Laufwerkbuchstabe ist erst nach einem Neustart verfügbar.
ErrorSource               :
ErrorSourceFormat         :
ErrorType                 :
Message                   : Nicht verfügbar
MessageArguments          :
MessageID                 : HRESULT 0x80041009
OtherErrorSourceFormat    :
OtherErrorType            :
OWningEntity              : Storage Volume WMI Provider
PerceivedSeverity         :
ProbableCause             :
ProbableCauseDescription  :
RecommendedActions        :
error_Category            : 0
error_Code                : 2147749897
error_Type                : HRESULT
error_WindowsErrorMessage : Nicht verfügbar
original_error            : __ExtendedStatus
PSComputerName            :

Quizfrage: Warum braucht es danach via Skript mglw. einen Neustart, wenn man es über die Datenträgerverwaltung macht aber nicht?

Gibt es irgendeinen Systemdienst den man ggf. neustarten kann stattdessen?
 
Zuletzt bearbeitet:
Warum Powershell?
Datenträgerverwaltung und gut
 
Weil es um ein Deploymentskript geht.
Ich möchte keine Einstellungen händisch durchführen.
Das mag für einzelne Systeme ausreichen, nicht aber wenn ich dutzende VMs erstellen möchte.

Im Moment habe ich mich aber so beholfen, dass ich den Buchstaben des CD/DVD-Laufwerks zuerst ändere und erst dann die zweite Festplatte mit GPT initialisiere, NTFS formatiere und einem Buchstaben einbinde.
Das erspart mir das Jonglieren mit den Buchstaben.
 
Wie oben schon geschrieben, das Laufwerk ist ziemlich sicher noch in Benutzung, schau dir mal die Beschreibung der /p Option von mountvol an
 
Nur mal eine weitere Idee. (ungetestet):

Eingabeaufforderung (Administrator):
Code:
diskpart
list vol # Die beiden Volume-Nr. der zu tauschenden Lw-Buchstaben merken/notieren
exit

Dann mit PowerShell weiter:

PowerShell:
$DrvLt = (Get-Volume | Where {$_.DriveType -Eq "CD-ROM"}).DriveLetter
If ($DrvLt -Eq "D")
{
    $removeCDR=@(
    "select volume 'NR'", # NR mit der Volume-Nr. der CD-ROM ersetzen
    'remove letter=D'
    )
    $removeCDR | diskpart
   
    $removeHDD=@(
    "select volume 'NR'", # NR mit der Volume-Nr. der HDD/SSD ersetzen
    'remove letter=E'
    )
    $removeHDD | diskpart
   
    $assignCDR=@(
    "select volume 'NR'", # NR mit der Volume-Nr. der CD-ROM ersetzen
    'assign letter=E'
    )
    $assignCDR | diskpart
}

[..]
# Lw D:
Initialize-Disk -Number $DskNr -PartitionStyle GPT -PassThru
# Lw F:
Initialize-Disk -Number $DskNr -PartitionStyle GPT -PassThru

u.s.w. u.s.f. (o.s.ähnlich)
 
Finger weg von solchem “Mischbetrieb” wenn es nicht absolut notwendig ist!

WMI/CIM bietet alles Erforderliche. Im Zweifel die Msdn befragen - alles was mit .net geht, geht in PS auch.

Wenn eine Mixtur aus PS und sowas wie diskpart erforderlich sein sollte (sehr unwahrscheinlich) dann eine Wrapperfunktion um diskpart bauen und sehr sehr SEHR gut aufpassen, dass unterwegs nix schiefgehen kann. Sonst sind mal so eben die völlig falschen Daten unwiederbringlich hinüber.

Fürs Deassignment von LW Buchstaben kann man über die Liste geöffneter Dateien gehen- müßte in fsutil stecken, nur lesend — oder kann nach den erforderlichen Flags in msdn gucken um Dismount zu erzwingen.

Kombination daraus und ein paar Standardchecks erscheint sinnvoll: Hab ich das fragliche Volume in $Pwd? Hab ich nen Prozeß der einen Pfad mit dem Buchstaben offen hat? Dann überlegen, wie in solchen Fällen verfahren werden soll.
 
RalphS schrieb:
Finger weg von solchem “Mischbetrieb” wenn es nicht absolut notwendig ist!
Ist grundsätzlich auch mein Motto.
Es gibt aber Situationen, da kann man sich nicht anders behelfen. Die sind aber sehr selten.

Es sollte auch nur ein Hinweis auf eine weitere Möglichkeit sein und ich habe weiter oben nicht umsonst den Hinweis "ungetestet" angefügt.

Warum jetzt allerdings "Daten unwiederbringlich hinüber" sein sollen, wenn man Laufwerksbuchstaben entfernt oder tauscht, erschließt sich mir nicht so recht.

Ich gehe in einem Bereich wie diesen hier davon aus, dass sich hier nicht die absoluten Anfänger tummeln, sondern vielmehr User, die im Großen und Ganzen wissen, was sie tun.
 
  • Gefällt mir
Reaktionen: RalphS
NotNerdNotDau schrieb:
Warum jetzt allerdings "Daten unwiederbringlich hinüber" sein sollen, wenn man Laufwerksbuchstaben entfernt oder tauscht, erschließt sich mir nicht so recht.
Das kann mit diskpart immer passieren, insbesondere wenn man inline drauf zugreift und BenutzerEingaben nicht (ausreichend) prüft. Dann ist es zwar kein sql injection, aber aus exakt demselben Grund “diskpart injection”.


NotNerdNotDau schrieb:
Ich gehe in einem Bereich wie diesen hier davon aus, dass sich hier nicht die absoluten Anfänger tummeln, sondern vielmehr User, die im Großen und Ganzen wissen, was sie tun.
Wünschte es wäre so… nichts gegen irgendjemanden, aber hier tummelt sich gefühlt alles von “Total Ahnungslos“ bis “Ich Dachte Ich Wüßte Wie“ und alles dazwischen. Leider einschließlich “ich weiß was ich tue, egal was die Realität mir sagt”. Plus ein paar verknöcherte Kameraden wie mich die denken ihr Weg sei der bessere, wieder egal was die Realität sagt.

Klar ist das über die Maßen zynisch und ich entschuldige mich für alle jetzt schmerzenden Füße. Aber dies ist eben kein Forum mit Ausrichtung auf Automatisierung, Programmierung, Scripting, was auch immer. Hier fragen hauptsächlich Laien, und auch wenn der jeweilige TO selbst keiner ist, so gibts trotzdem noch genug Mitleser.

Deswegen ist es zwar irgendwie doof, aber trotzdem essentiell, (jedesmal) problematische Ecken explizit herauszustellen.
 
  • Gefällt mir
Reaktionen: NotNerdNotDau
Um kurz mal eine Rückmeldung zugeben.
Ich habe den Buchstabentausch jetzt nicht weiter verfolgt - das teste ich vlt. ein ander Mal noch mal aus.

Ich belasse es dabei, dass ich im Skript den Buchstaben des optischen Laufwerks zuerst ändere und dann die zweite Festplatte initialisiere.

Das funktioniert so am einfachsten.

Dennoch danke an alle die Input gegeben haben.
 
  • Gefällt mir
Reaktionen: NotNerdNotDau
Zurück
Oben