dedphish
dedphish

Reputation: 1

PowerShell -contains only working as expected, if the referenced list is referenced separately beforehand

I am perplexed to say the least. Currently working on a PowerShell script to deploy SharePoint Libraries to users via Intune.

I use a custom detection script, which checks the folder-attribute sync-status of a folder, before syncing (this is hacky, but apparently about as reliable as it gets when it comes to checking if a OneDrive folder is synced or not.

In the function to check the sync status, I use a -contains condition, to check if the value matches one of a list of predefined sync-status-strings:

function Test-SPFolderSyncStatus {

    param (
        [string]$folderPath
    )

    # Define lists of OneDrive status values
    $odSyncedValues = @(
        # English
        "Available when online",
        "Available on this device",
        "Always available on this device",
        "Syncing",

        # German
        "Verfügbar, wenn online",
        "Auf diesem Gerät verfügbar",
        "Immer auf diesem Gerät verfügbar",
        "Synchronisierung ausstehend",
        "Synchronisierung läuft"
    )

    # Check if folder exists
    if(!(Test-Path -Path $folderPath)) {
        return $false
    }

    # If the folder exists - check sync status
    $shell = (New-Object -ComObject Shell.Application).NameSpace((Split-Path $folderPath))
    $status = $shell.GetDetailsOf(($shell.ParseName((Split-Path $folderPath -Leaf))),303)

    if ($status -in $odSyncedValues) {
        return $true
    }
    else {
        return $false
    }
}

This function does not work as intended: even when I print $status, and it is equal to a string in my sync-value list, the function returns false.

I then tried debugging, by outputting the array to the CLI, this is where the major confusion arose.

When I put $odSyncedValues just on its own, just before the if (which I originally did to debug), the -contains starts working as intended???

So this works:

    // Rest of the script stays the same
    $odSyncedValues

    if ($status -in $odSyncedValues) {
        return $true
    }
    else {
        return $false
    }

But this doesnt:

    // Rest of the script stays the same
    // no $odSyncedValues
    if ($status -in $odSyncedValues) {
        return $true
    }
    else {
        return $false
    }

What causes this? Can I get it to work as intended without mentioning the variable?

Upvotes: 0

Views: 23

Answers (1)

dedphish
dedphish

Reputation: 1

I've found the issue - it has to do with the encoding of special characters.

My issue was with "Verfügbar, wenn online", the single reference to $odSyncedValues seems to force PowerShell to encode strings properly, while the same thing does not happen when it is referenced only in the condition?

I am still not entirely clear on how this happens, which is why I'll leave the question up for now.

But the "fix" is to do:

    $odSyncedValues = $odSyncedValues | ForEach-Object {
        [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::Default.GetBytes($_))
    }

Upvotes: 0

Related Questions