Immer wieder begegne ich der Anforderung, dass der Desktop (oder auch anderer Ordner), die mit OneDrive synchronisierte sind, immer offline verfügbar sein müssen. Alle OneDrive-Ordner offline verfügbar zu machen, führt oft zu mehr Problemen, da der lokale Speicher möglicherweise nicht ausreicht. Jeder User könnte theoretisch einmalig auf den entsprechenden Ordner klicken und die Option anwählen. Viel schöner können wir das aber auch mit einem PowerShell Script und einem Proactive Remediation Paket lösen. So stellen wir sicher, dass auch neue Order oder falls der User diese abwählt, offline verfügbar bleiben.

Table of Contents

Spezifischen Ordner offline behalten

Sobald du in OneDrive auf einem Ordner "Immer offline verfügbar" wählst, ändert sich ein Attribut in diesem und allen darunterliegenden Daten. Diesen Change können wir auch mit PowerShell und der "attrib.exe" nachverfolgen und natürlich durchführen. (attrib | Microsoft Learn)

Wie die Attribute sind und was in den verschiedenen Status ändert, kannst du so auslesen:
attrib.exe "C:\..\Desktop"

attrib.exe Folder

Zwischen den beiden Abfragen habe ich die Option manuell aktiviert. Das heisst also, wir müssen das Attribut "U" entfernen und durch ein "P" ersetzen.

Den OneDrive-Desktop machst du nun mit folgendem Befehl offline verfügbar:
attrib.exe "C:\..\Desktop" -U +P /s /d

Damit fehlen uns aber noch die Verfügbarkeit des Inhalts. Wie die Attribute dieser sein müssen, finden wir auch anhand eines Beispiels heraus:
attrib.exe "C:\..\Desktop\Demo.docx"

attrib.exe File

Die Attribute hier passen wir so an:
Get-ChildItem "C:\..\Desktop" -Recurse | Select-Object Fullname | ForEach-Object { attrib.exe $_.FullName -U +P }

Das Ganze zusammen als simples Skript sieht dann so aus:

$CompanyName = "scloud"
$Folder = "Desktop"

# OneDrive Path
$OneDrive_path = "$($home)\OneDrive - $CompanyName\$Folder"

# Process main folder 
attrib.exe $OneDrive_path -U +P /s /d

# Process child items 
Get-ChildItem $OneDrive_path -Recurse | Select-Object Fullname | ForEach-Object { attrib.exe $_.FullName -U +P }Code language: PHP (php)

Proactive Remediation

Um auch Useraktionen entgegenzuwirken (falls ein User den Desktop "desynchronisiert"), habe ich für den oben beschriebenen Ablauf ein Proactive Remediations Paket erstellt. Dieses habe ich dir wie üblich auf GitHub abgelegt.

Falls du keine Enterprise Windows Version in deinem Unternehmen einsetzt, kannst du die Proactive Remediations Funktion in Intune nicht nutzen. Dazu habe ich dir aber das "Proactive Remediation for Business" Paket abgelegt.

Detection

In der Detection überprüfe ich als Erstes, ob der Ordner im richtigen Zustand ist.
Dazu vergleiche ich den Output der attrib.exe mit dem gewünschten Zielzustand. Falls dieser nicht wie gewünscht ist, wird die Detection mit dem Exitcode "1" beendet und löst so die Remediation aus:

# Retrieve the attributes of the OneDrive_path using attrib.exe command
$MainStatus_current = $(attrib.exe $OneDrive_path) -replace(" ","")

# Create MainStatus_target variable by concatenating "RP" and OneDrive_path, then remove any whitespace characters
$MainStatus_target = "RP"+$($OneDrive_path) -replace(" ","")

# Compare MainStatus_current and MainStatus_target. If they are not equal, print a warning message and exit with status code 1.
if($MainStatus_current -ne $MainStatus_target){
    Write-Warning "Not offline aviable: $OneDrive_path"
    exit 1
}
Code language: PowerShell (powershell)

Ist der Ordner bereits offline verfügbar, werden noch alle Inhalte geprüft. Sobald einer als nicht verfügbar anschlägt, wird die Detection beendet und löst wie beim Ordner mit dem Exitcode "1" die Remediation aus.

# Get all Child Items
$ChildItems = Get-ChildItem -Path $OneDrive_path -Recurse

# Loop through each child item
Foreach($child in $ChildItems){
    # Retrieve the attributes of the item using attrib.exe command
    $ChildStatus_current = $(attrib.exe $child.FullName) -replace(" ","")
    # Define the desired status of the child item by prepending "AP" to its full name
    $ChildStatus_target = "AP"+$($child.FullName) -replace(" ","")
    # If current status of the child does not match the desired status, exit with 1
    if($ChildStatus_current -ne $ChildStatus_target){
        Write-Warning "Not all files are offline aviable."
        exit 1
    }
}Code language: PowerShell (powershell)

Schlägt weder der Ordner noch eine Datei in diesem an, wird die Detection mit dem Exitcode "0" beendet und löst nichts weiter aus.

Tritt ein Fehler auf, wird die Detection ebenfalls mit "1" beendet.

Remediation

Die Remediation ist eigentlich genau das Script von oberhalb, welches den Ordner und die darin enthaltenen Dateien auf "offline verfügbar" setzt. Mit dem Unterschied, dass auch noch eine kleines Error Handling darum gebaut ist.

$CompanyName = "scloud"
$Folder = "Desktop"

try{

    # OneDrive Path
    $OneDrive_path = "$($home)\OneDrive - $CompanyName\$Folder"

    # Process main folder 
    attrib.exe $OneDrive_path -U +P /s /d

    # Process child items 
    Get-ChildItem $OneDrive_path -Recurse | Select-Object Fullname | ForEach-Object { attrib.exe $_.FullName -U +P }

}catch{
    Write-Error $_
}
Code language: PowerShell (powershell)

Konfiguration in Intune

Das Proactive-Remediations-Paket erstellst du in Intune unter:
Reports > Endpoint analytics > Proactive remediations > Create script package

New Proactive Remediations

In den Settings lädst du die beiden Scripts wie folgt hoch:

Proactive Remediations, detection and remediation

Scope-Tags brauchst du nur, falls du sie in deiner Organisation verwendest.

Zum Schluss weisst du das Paket noch zu und definierst einen Schedule:

Proactive Remediations, assignment and schedule

Das wars, nun wird die Prüfung täglich durchgeführt und falls nötig das nötige Attribut gesetzt.