Een van de belangrijkste coderingsmethodologieën om te volgen is ervoor te zorgen dat je weet en beheert op welke manieren je code kan “stromen”. Als je je code als een stroom beschouwt, kan deze vertakken, terugkeren naar verschillende punten en vele voorwaarden tegenkomen.
Foutafhandeling zorgt ervoor dat je “netten” of een standaardplaats instelt waar je code naartoe kan stromen wanneer er iets onverwachts gebeurt.
Laten we een scenario uit de echte wereld gebruiken waarin je jezelf kunt bevinden, met het omgaan van PowerShell foutafhandeling.
Het Opbouwen van het Initiële Script voor Bestandsopruiming
We moeten een aantal oude bestanden opruimen. Onze bestandenserver bestaat al eeuwen en we moeten wat ruimte vrijmaken. Het management heeft besloten om alle bestanden ouder dan een bepaald aantal dagen te verwijderen. We moeten een script bouwen dat een map recursief doorzoekt, alle bestanden ouder dan een bepaald aantal dagen vindt en ze verwijdert.
De taak klinkt eenvoudig genoeg, maar dit is de foutafhandelingssectie, dus je weet dat er dingen mis zullen gaan!
Laten we beginnen met het begrijpen van foutafhandeling door eerst het demoscenario-script zonder foutafhandeling te bouwen om het probleem te demonstreren dat foutafhandeling oplost.
-
Eerst, open een nieuw VS Code-tabblad.
Aangezien we nu gewoon een paar dingen uitproberen, zullen we het script nog niet opslaan. Vertel VS Code tijdelijk dat je op het punt staat om wat PowerShell te schrijven.
Druk op Ctrl-Shift-P, typ ‘lang’, selecteer Kies Taalmodus, typ ‘power’ en kies PowerShell. Nu weet VS Code dat je PowerShell gaat schrijven.
-
Als volgende stap, deel het probleem op in taken en los de meest voor de hand liggende eerst op.
In dit geval komt de taak met een commando om bestanden in een map te lezen.
Get-ChildItem -Path C:\OudeVergetenMap
-
Get-ChildItem
retourneert ook mappen die we niet nodig hebben, dus laten we dat beperken tot alleen bestanden.Get-ChildItem -Path C:\OudeVergetenMap -File
-
Als er bestanden in die submappen zijn, moeten we ze ook ophalen met
Recurse
.Get-ChildItem -Path C:\OudeVergetenMap -File -Recurse
-
Nu we het commando en de parameters hebben, retourneert het ALLE bestanden. We moeten alleen de bestanden vinden die ouder zijn dan een bepaald aantal dagen.
Aangezien
Get-ChildItem
elk bestand retourneert met eenLastWriteTime
objecteigenschap, moeten we filteren op die eigenschap. We zullen deWhere
filter gebruiken om de bestanden te vinden met eenLastWriteTime
die minder is dan een opgegeven datum.(Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
-
De datum moet dynamisch zijn omdat “oud” vandaag anders is dan “oud” morgen.
Commentaar op de vorige regel omdat we deze op een bepaald moment nodig zullen hebben en dan de datumsituatie moeten bekijken.
## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????} $Now = Get-Date $Now
-
Nu we de datum van vandaag hebben, laten we een specifiek aantal dagen voor vandaag vinden om de datum te achterhalen. Ik zal hier tijdelijk
30
invullen, omdat ik weet dat sommige bestanden ouder zijn dan vijf dagen voor een rudimentaire test.## (Get-ChildItem -Path C:\\OudeVergetenMap -File -Recurse).Waar{$_.LastWriteTime -le ?????} $Nu = Get-Date $LaatsteSchrijven = $Nu.AddDays(-30) $LaatsteSchrijven
-
Klaar! Laten we tot nu toe alles samenvoegen.
$Nu = Get-Date $LaatsteSchrijven = $Nu.AddDays(-30) (Get-ChildItem -Path C:\OudeVergetenMap -File -Recurse).Waar{$_.LastWriteTime -le $LaatsteSchrijven}
We hebben nu een klein script dat alle bestanden in een map vindt die ouder zijn dan een specifiek aantal dagen.
-
Vervolgens moeten we de mogelijkheid toevoegen om die oudere bestanden te verwijderen. Dit is triviaal met behulp van de
Remove-Item
cmdlet en de pipeline.$Nu = Get-Date $LaatsteSchrijven = $Nu.AddDays(-30) (Get-ChildItem -Path C:\OudeVergetenMap -File -Recurse).Waar{$_.LastWriteTime -le $LaatsteSchrijven} | Remove-Item
-
Gedaan! Maar wacht, ik heb geen idee welke bestanden het heeft verwijderd. Er waren ook enkele fouten die we over een paar minuten zullen behandelen. Laten we wat basisfunctionaliteit toevoegen.
$VerbosePreference = 'Doorgaan' $Now = Get-Date $LastWrite = $Now.AddDays(-30) $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite} foreach ($file in $oldFiles) { Remove-Item -Path $file.FullName Write-Verbose -Message "Succesvol verwijderd [$($file.FullName)]." }
-
Je moet een lus zoals deze opnemen om een soort code voor elk bestand uit te voeren. Hier gebruiken we de pipeline niet en plaatsen we in plaats daarvan alle gevonden bestanden in een
oldFiles
variabele, een array van bestandobjecten. We voeren vervolgensRemove-Item
op elk bestand uit zoals voorheen, maar deze keer inclusief een gedetailleerd bericht dat ons vertelt welk bestand wordt verwijderd. -
Laten we nu deze code uitvoeren en kijken wat er gebeurt.
Je kunt nu via het gedetailleerde bericht zien dat er enkele bestanden zijn verwijderd. De code die we nu hebben, is de essentie die we nodig hebben om het script te maken. Laten we nu een echt script vanuit dit voorbeeld in de volgende sectie maken.
Maximaliseren van flexibiliteit en herbruikbaarheid met parameters
Je hebt je script gebouwd, maar het heeft nog steeds het potentieel om flexibel en herbruikbaar te zijn. Hoe? Parameters stellen ons in staat om de directory en de leeftijd van de bestanden die we willen targeten op te geven, waardoor het script flexibeler wordt.
-
Voordat we verder gaan, laten we ons werk opslaan. Noem het Remove-FileOlderThan.ps1.
Merk de werkwoord/zinsnede-indeling met een koppelteken op. Probeer indien mogelijk altijd scriptnamen op dezelfde manier te maken als PowerShell-opdrachten voor consistentie en leesbaarheid.
-
Eerst zijn scripts bedoeld om herbruikbaar te zijn. De kans is groot dat je dit script waarschijnlijk op verschillende mappen en verschillende leeftijden wilt gebruiken. We moeten enkele parameters introduceren. Om dat te doen, bepalen we wat zal veranderen. De map en het aantal dagen. Begrijp je het.
param ( [Parameter(Mandatory)] [string]$FolderPath,
[Parameter(Mandatory)] [int]$DaysOld
)
$Now = Get-Date
$LastWrite = $Now.AddDays(-30)
$oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
foreach ($file in $oldFiles) {
Remove-Item -Path $file.FullName
Write-Verbose -Message "Succesvol verwijderd [$($file.FullName)]."
}Voeg een
param
blok bovenaan toe en definieer elke parameter als verplicht, aangezien we een pad en een getal nodig hebben voor het script om te functioneren. Specificeer ook het type hier als beste praktijk. -
Vervang de statische items die we eerder in de code hadden door de parameterwaarden.
param ( [Parameter(Mandatory)] [string]$FolderPath,
[Parameter(Mandatory)] [int]$DaysOld
)
$Now = Get-Date
$LastWrite = $Now.AddDays(-$DaysOld)
$oldFiles = (Get-ChildItem -Path $FolderPath -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
foreach ($file in $oldFiles) {
Remove-Item -Path $file.FullName
Write-Verbose -Message "Succesvol verwijderd [$($file.FullName)]."
} -
Laten we nu het script uitvoeren en zien wat er gebeurt.
C:\Scripts\Remove-FileOlderThan.ps1 -FolderPath C:\OldForgottenFolder -DaysOld 30 -Verbose
Je kunt zien hoe we het pad van de map en het aantal dagen oud als parameters moeten opgeven. Gebruik de
Verbose
parameter om dieWrite-Verbose
regel te zien.PowerShell voerde het script precies uit zoals voorheen, maar we hebben nu een geparameteriseerd script dat we op elke map of elke leeftijd van bestanden kunnen gebruiken!
Als we naar de uitvoer kijken, zien we wat rode tekst. Of je hebt geen rechten, of het bestand is alleen-lezen. Maar op welke bestanden is het mislukt? En hoe zorg je ervoor dat die bestanden ook worden verwijderd?
Conclusie
In deze tutorial hebben we een script gebouwd om oude bestanden uit een map op te ruimen, waarbij we flexibiliteit hebben gegarandeerd door parameters toe te voegen. Hoewel het script werkt zoals bedoeld, zagen we dat foutafhandeling nog niet was behandeld, wat cruciaal is bij het omgaan met scenario’s uit de echte wereld.
Als we verder gaan, zal het toevoegen van foutbeheer ons in staat stellen om problemen te behandelen, zoals cmdlets die fouten genereren of bestanden die niet toegankelijk zijn, waardoor we scriptterminatie kunnen vermijden en gedetailleerde inzichten krijgen in wat er misging.
Blijf op de hoogte voor de volgende demo! PowerShell 101: Terminerende, Niet-Terminering Fouten, en Proberen/Vangen.
Source:
https://adamtheautomator.com/powershell-file-cleanup-script/