celiko
Goto Top

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:
  • 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

Content-Key: 73455095304

Url: https://administrator.de/contentid/73455095304

Printed on: July 14, 2024 at 16:07 o'clock

Member: CamelCase
Solution CamelCase Jun 18, 2024 updated at 12:07:33 (UTC)
Goto Top
Moin,

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.
Mitglied: 13034433319
Solution 13034433319 Jun 18, 2024 updated at 12:25:22 (UTC)
Goto Top
$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)
    }
}
Oder gleich mit mit choco abfackeln, da Webseiten sich mit der Zeit ändern können und man dann wieder ans Skript ran muss.
https://community.chocolatey.org/packages/fslogix
# install
choco install fslogix
# upgrade
choco upgrade fslogix
Gruß
Member: ThePinky777
ThePinky777 Jun 18, 2024 at 13:28:11 (UTC)
Goto Top
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.
Member: Celiko
Celiko Jun 18, 2024 at 13:47:19 (UTC)
Goto Top
Danke an die Vorschläge / Ideen, werde es mal gleich in mein Script einbauen
Ich wusste doch, dass das besser geht :D

VG
Member: Michi91
Michi91 Jun 18, 2024 at 14:03:30 (UTC)
Goto Top
+1 für choco