Så här hanterar du öppna filhandtag med PowerShell

Julia Tim/Shutterstock

Ett av de mer frustrerande felen som en slutanvändare eller IT-administratör kan hantera är att låsta filer i Windows. När du tar bort en mapp, flyttar en fil eller redigerar en konfiguration och du stöter på ett låst filfelmeddelande är det bättre att hantera det snabbt och effektivt.

Microsoft introducerade PowerShell som ersättning. shell, men det har mycket mer funktionalitet än så och är ett komplext och kapabelt språk. Låt oss titta i den här artikeln på hur du kan använda PowerShell för att hantera låsta filer.

Problemet med låst fil

Hur låses en fil exakt? Under normal användning skapar en process många handtag till resurser som en fil. Genom att göra det låser processerna ofta filen för att förhindra oavsiktliga konfigurationsändringar eller annan korruption. Problemet är ofta att det är svårt att avgöra vilken process som har låst filen och därefter hur man tar bort låset från filen.

Tyvärr finns det ingen inbyggd cmdlet för att testa en fil och berätta om den är låst eller genom vilken process. Därför måste du skapa dina egna funktioner eller sätta in andra användbara verktyg som finns för att hjälpa till att ta reda på mer om dessa filer.

Testning för låsta filer

Inom Windows kan du testa om en enskild fil är låst. Med hjälp av följande kodblock kan du testa om en viss fil är låst. Variabeln $ Item måste ställas in till en fullständig filsökväg. Genom att testa för att se om filen kan öppnas för skrivning, som visas med kommandot [System.IO.File] :: Open ($ Item, 'Open', 'Write'), kan du se om filen är låst.

Om ([System.IO.File] :: Exists ($ Item)) {Prova {$ FileStream = [System.IO.File] :: Open ($ Item, 'Open', 'Write') $ FileStream.Close () $ FileStream.Dispose () $ IsLocked = $ False} Catch [System.UnauthorizedAccessException] {$ IsLocked = 'AccessDenied'} Catch {$ IsLocked = $ True}}

Get-SMBOpenFile

Jag sa att Windows inte har en inbyggd funktion, men det finns ett fall där en funktion finns. Om du har en fjärrdelning eller till och med administrativa resurser (som c $) kan du använda Get-SMBOpenFile-cmdlet för att rapportera om de öppna filerna.

PS C: & gt; Get-SMBOpenFile FileId SessionId Path ShareRelativePath —— ——— —- —————– 154618822665 154618822657 C: PS C : & gt;

Nackdelen är att detta bara fungerar för filer som kan nås på distans. Alla låsta filer som används i ditt lokala system kommer inte att rapporteras om, så i de flesta fall är detta inte en lönsam lösning. För att stänga kan du pipa de öppna filerna som returneras till kommandot Close-SMBOpenFile.

Get-SMBOpenFile | Close-SMBOpenFile

OpenFiles-verktyg

Windows har ett inbyggt verktyg med namnet openfiles som kan hjälpa till att lista vilka filer som används och koppla bort dem. Vid första anblicken ser det perfekt ut efter dina behov! Du kan till och med slå in detta i en PowerShell-funktion för att underlätta frågan och koppla bort filer.

Öppna en administrativ PowerShell-fråga och kör kommandot openfiles/query. Omedelbart bör du få ett felmeddelande om att & # 8220; underhålla objektlistan & # 8221; den globala flaggan måste vara på.

PS C:/& gt; openfiles/query INFO: Systemets globala flagga 'underhåll objektlista' måste aktiveras för att se lokala öppnade filer. Se Openfiles /? för mer information. Filer öppnas på distans via lokala delningspunkter: —————————————— — INFO: Inga delade öppna filer hittades.

Denna objektlista är det som faktiskt underhåller listan över handtag som används och gör det möjligt för openfiles att fråga efter den informationen. För att aktivera detta, skriv in openfiles/local på och starta sedan om datorn. Nackdelen med att aktivera den här funktionen är att det finns en liten prestationshit, vilket beroende på ditt system kanske inte är värt att använda verktyget. Med det sagt, låt oss se hur vi kan få detta att fungera inom PowerShell.

PS C: & gt; openfiles/Query/fo csv/nh Filer öppnas på distans via lokala delningspunkter: ———————————- ———– “ID”, “Åtkomst till”, “Typ”, “Öppna fil (sökväg körbar)” “608”, “användare”, “Windows”, “C: ” PS C: & gt; openfiles/Query/fo csv | Select-Object -Skip 4 | ConvertFrom-CSV ID nås av typ Öppna fil (sökväg körbar) – ———– —- ——————- ——– 608 användare Windows C: PS C: & gt; openfiles/disconnect/id 608 SUCCESS: Anslutningen till den öppna filen “C: ” har avslutats.

Med de tidigare exemplen kan du se hur man importerar CSV-utdata från openfiles till PowerShell. Med den informationen kan du sedan koppla bort en fil för att låsa upp den. På grund av prestationshittet du kan drabbas av genom att aktivera listan för underhållsobjekt kanske det inte lönar sig för dina behov. På grund av detta kan andra lösningar behövas.

Handtagsprogrammet

Sysinternals är känt för sina många användbara och nästan nödvändiga IT-verktyg. För en tid sedan förvärvades Sysinternals av Microsoft, och du kan ladda ner och använda dessa välstödda verktyg för dig själv. Det finns bekvämt ett program som heter handtag som ger exakt det du letar efter!

Först måste du ladda ner programmet, packa upp filerna och placera körbarna på en plats som din Path-miljövariabel har inkluderat . Genom att göra det kan du enkelt referera till applikationen var du än behöver den. Med en enkel fråga för öppna filer kan du se att du får många resultat (avkortade för läsbarhet).

PS C:/& gt; handle64 -NoBanner … ——————————————– ———————————- RuntimeBroker.exe pid: 9860 Användare 48: Fil C: Windows System32 188: Section BaseNamedObjects __ ComCatalogCache__ 1EC: Section BaseNamedObjects __ ComCatalogCache__ ———————————— —————————————— chrome.exe pid: 4628 Användare 78 : Fil C: Programfiler (x86) Google Chrome Application 78.0.3904.108 1C4: Avsnitt Sessions 1 BaseNamedObjects windows_shell_global_counters …

Du verkar få vad du vill ha & # 8212; åtminstone en sätt att ta reda på vilka filer som används & # 8212; och du kan testa dem med din fillåsta kod från tidigare. Men hur gör du det lättare att använda? Följande kod läser varje process och hämtar bara de låsta filerna. Nackdelen är att det tar ett tag att köra eftersom det finns många processer.

$ Processer = Get-Process $ resultat = $ Processer | Foreach-Object {$ handles = (handle64 -p $ _. ID -NoBanner) | Var-objekt {$ _ -Match “File”} | Foreach-Object {[PSCustomObject] @ {“Hex” = ((($ _ -Split “”). Var ({$ _ -NE “”}) [0]). Dela (“:”) [0]) .Trim () “File” = (($ _ -Split “”) [- 1]). Trim ()}} If ($ handles) {[PSCustomObject] @ {“Name” = $ _. Namn “PID” = $ _. ID “Handles” = $ handles}}}

I slutändan är det som du får en handlingsbar samling av filer, listade efter process, som du vet är i bruk och kan filtreras ytterligare. Om du upptäcker att du måste stänga en av dem kan du göra följande (som administratör):

PS C: & gt; $ resultat | & gt; & gt; Where-Object Name -EQ 'Anteckningar' | & gt; & gt; Var-objekt {$ _. Handles.File -Match “test.txt”} Namn PID-handtag —- — ——- Anteckningsblock 12028 {@ {Hex = 44; Fil = C: test.txt} PS C: & gt; handle64 -p 12028 -c 44 -y -nobanner 44: File (R-D) C: test.txt Handtag stängt.

Du kan ytterligare lägga in allt detta i en funktion för att göra det ännu enklare att analysera och söka efter behov. Många möjligheter finns, särskilt när man kombinerar de olika metoderna till en lösning som passar din miljö.

Slutsats

Att hantera låsta filer kan vara en utmaning, särskilt när det stoppar vad du behöver för att få gjort snabbt. Det finns ett antal sätt att hitta och låsa upp dessa filer, men det kräver lite arbete eftersom Windows inte har en riktigt omfattande inbyggd metod för att hantera dessa låsta filer. De beskrivna lösningarna bör göra korta arbeten med vad som än är och låta dig gå vidare till mycket viktigare uppgifter!


Posted

in

by

Tags: