Powershell - Verbesserungsvorschlag - Invoke-Webrequest
Moin,
ich will gerne neue Versionen von Software auf meinem Netzlaufwerk automatisch ablegen lassen.
Hintergrund ist, dass ich für meinen DEV-Server immer die neuste Software vollautomatisch installieren lassen möchte per Powershell (ist eine AVD).
Jetzt wollte ich ein eigenes Script für bspw. den FSLogix bauen, der folgendes tut:
Hier mein Script:
Das Script funktioniert... aber irgendwie gefällt es mir nicht.
Den Server anzuweisen die neuste Version zu installieren aus dem Netzlaufwerk ist dann ein Kinderspiel und gefühlt ein 3-Zeiler mit IF-Abfrage.
An die PS-Experten... Das geht doch bestimmt besser, oder nicht? 😅
Habe das Gefühl, dass ich es extrem unelegent gelöst habe.
Die Auswahl der Variablen kann auch verbessert werden, oder?
VG
Celikoo
ich will gerne neue Versionen von Software auf meinem Netzlaufwerk automatisch ablegen lassen.
Hintergrund ist, dass ich für meinen DEV-Server immer die neuste Software vollautomatisch installieren lassen möchte per Powershell (ist eine AVD).
Jetzt wollte ich ein eigenes Script für bspw. den FSLogix bauen, der folgendes tut:
- Untersuche die Seite, ob es Links gibt, die mit *.zip enden.
- Benutze ein Regex, um den Dateinamen zu filtern
- Überprüfe, welche Version aktueller ist
- Wenn nicht vorhanden downloade die Datei und lege sie im Netzlaufwerk ab
Hier mein Script:
$pattern = '[^/\\&\?]+\.\w{3,4}(?=([\?&].*$|$))'
$FSLogix_Latest = ((Invoke-WebRequest -UseBasicParsing –Uri ' https://learn.microsoft.com/en-us/fslogix/overview-release-notes').Links | Where-Object {$_.href -like "*.zip"})
$a = [System.Collections.ArrayList]@()
Foreach ($FSLogix_Version in $FSLogix_Latest) { $a.Add([regex]::Matches($FSLogix_Version.href, $pattern).Value)}
$a | Sort-Object -Descending
$Download_Path = "C:\Temp\"
if (!(Test-Path ($Download_Path + $($a[0])))) {
Invoke-WebRequest -Uri ($FSLogix_Latest.href | Where-Object {$_ -like "*$($a[0])*"}) -OutFile ($Download_Path + $($a[0]))
}
Das Script funktioniert... aber irgendwie gefällt es mir nicht.
Den Server anzuweisen die neuste Version zu installieren aus dem Netzlaufwerk ist dann ein Kinderspiel und gefühlt ein 3-Zeiler mit IF-Abfrage.
An die PS-Experten... Das geht doch bestimmt besser, oder nicht? 😅
Habe das Gefühl, dass ich es extrem unelegent gelöst habe.
Die Auswahl der Variablen kann auch verbessert werden, oder?
VG
Celikoo
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 73455095304
Url: https://administrator.de/contentid/73455095304
Ausgedruckt am: 21.11.2024 um 14:11 Uhr
5 Kommentare
Neuester Kommentar
Moin,
ich würde es so machen, um nur die neueste Version zu laden
Edit: Nochmal überarbeitet, um z.B. eine Version 2.10 korrekt neuer als 2.9 einzusortieren. Bei deinem Skript und auch meinem alten wäre 2.9 neuer als 2.10.
Ich würde auch noch in Erwägung ziehen, System.Net.WebClient oder auch BitsTransfer anstatt Invoke-WebRequest zu verwenden, die sind deutlich schneller.
ich würde es so machen, um nur die neueste Version zu laden
$url = "https://learn.microsoft.com/en-us/fslogix/overview-release-notes"
$destinationDir = "C:\temp"
# Helferfunktion, extrahiert Version aus Link
function Get-VersionFromLink {
param ($link)
if ($link -match "FSLogix_Apps_([\d\.]+)\.zip") {
return [version]$matches[1]
} else {
return [version]"0.0.0.0"
}
}
# Den neuesten Link abrufen
$zipLink = ((Invoke-WebRequest -UseBasicParsing -Uri $url).Links | Where-Object { $_.href -match "\.zip$" }).href | Sort-Object { Get-VersionFromLink $_ } -Descending | Select-Object -First 1
# Anstatt des RegEx: GetFileName
$fileName = [System.IO.Path]::GetFileName($zipLink)
# Anstatt dem String-Gebastel: Join-Path
$destinationFile = Join-Path -Path $destinationDir -ChildPath $fileName
# Datei runterladen
Invoke-WebRequest -Uri $zipLink -OutFile $destinationFile
Edit: Nochmal überarbeitet, um z.B. eine Version 2.10 korrekt neuer als 2.9 einzusortieren. Bei deinem Skript und auch meinem alten wäre 2.9 neuer als 2.10.
Ich würde auch noch in Erwägung ziehen, System.Net.WebClient oder auch BitsTransfer anstatt Invoke-WebRequest zu verwenden, die sind deutlich schneller.
$destinationPath = "C:\temp"
$wc = [System.Net.WebClient]::new()
$latest = [regex]::matches($wc.DownloadString('https://learn.microsoft.com/en-us/fslogix/overview-release-notes'),'(?i)https://[^<]+FSLogix_Apps_[\d\.]+\.zip').Value | sort {[version][regex]::match($_,'[\d\.]+(?=\.zip)').Value} -Descending | select -First 1
if ($latest){
$dest = join-path $destinationPath ([IO.Path]::GetFileName($latest))
if (!(Test-Path $dest -PathType Leaf)){
$wc.DownloadFile($latest,$dest)
}
}
https://community.chocolatey.org/packages/fslogix
# install
choco install fslogix
# upgrade
choco upgrade fslogix
Ich hab mal sowas gebaut aber anders.
Ich habe immer die Datei gedownloaded.
Dann lokal die Setupdatei Version verglichen mit der existierenden.
Und wenn runtergeladene neuer dann entsprechend ins Paket kopiert.
Weil webseite auslesen usw... ist halt so hm... sagen wir mal Glücksache (Wenn sich die webseite nie ändert gehts...
Natürlich wenn das File zum downloaden auch jedesmal anders heisst ist es auch doof...
Nur so mein Gedanke dazu.
Ich habe immer die Datei gedownloaded.
Dann lokal die Setupdatei Version verglichen mit der existierenden.
Und wenn runtergeladene neuer dann entsprechend ins Paket kopiert.
Weil webseite auslesen usw... ist halt so hm... sagen wir mal Glücksache (Wenn sich die webseite nie ändert gehts...
Natürlich wenn das File zum downloaden auch jedesmal anders heisst ist es auch doof...
Nur so mein Gedanke dazu.