Forum Discussion
Is there any way to get the sync status using PowerShell Script?
The dll mentioned in this thread is good, but I don't want to have to distribute that to everyone's machines, so I came up with an alternative. The script that follows would check OneDrive for a folder called Documents and returns its status.
# ID 303 = "Availability status" | The status is generally one of the following...
# "Always available on this device", "Available on this device", "Available when online"
$OneDriveDocs = "$env:OneDrive\Documents"
$Shell = (New-Object -ComObject Shell.Application).NameSpace((Split-Path $OneDriveDocs))
$Status = $Shell.getDetailsOf(($Shell.ParseName((Split-Path $OneDriveDocs -Leaf))),303)
- martinzimaNov 20, 2022Copper Contributor
Hi steveprentice,
Thanks for your post!... Interestingly, I spent a lot of time trying to do the same thing myself as was sure I had seen a Windows file property for this but just couldn't get it to work when I tried it. Sadly, after running your code, I got $status = "" and when I manually checked prop:303 using another util I have it didn't show any value for this either... Am wondering if maybe Microsoft recently removed/deprecated this property?
- BoydHeeresOct 01, 2023Copper Contributor
Hi martinzima,
You and steveprentice send me down a rabithole with your conversation.
I did some digging into what you both mentioned and I figured out that the command only works when you query the folder you are currently in.
With the help of an LLM AI I created a function that reads the information from all the files in the OneDrive and outputs it back out of the function as an object.
It is still not perfect, I just noticed that the .exe files are not properly detected for whatever reason and I suspect I will encounter a few more.
If I remember I will update this site once I have completed it.$Shell = New-Object -ComObject Shell.Application function Get-ShellDetails { param ( [string]$DirectoryPath ) $ShellNamespace = $Shell.NameSpace($DirectoryPath) $Items = $ShellNamespace.Items() foreach ($Item in $Items) { if ($Item.IsFolder -and -not ($Item.Path -match '\.(zip|tar\.gz|7z|rar|tar|gz|bz2|xz|cab|lzma)$')) { Get-ShellDetails -DirectoryPath $Item.Path # Recursive call for nested directories } elseif (-not ($Item.Path -match '\.(zip|tar\.gz|7z|rar|tar|gz|bz2|xz|cab|lzma)$')) { $ShellDetails303 = $ShellNamespace.getDetailsOf($Item, 303) $MergedObject = [PSCustomObject]@{ FullName = $Item.Path Attributes = (Get-Item -Path $Item.Path).Attributes ShellDetails303 = $ShellDetails303 } $MergedStatus.Add($MergedObject) } } - steveprenticeNov 27, 2022Brass Contributor
martinzima Hey. So I've been playing with that this evening and although I still have the same properties here I've have taken a different tack, hopefully it'd help you. The below checks if something's Pinned (i.e. Always Available), and if not, sets it to be. Seems to work well for me.
$FILE_ATTRIBUTE_PINNED = 0x00080000 $path = "$env:OneDrive\Documents" $folder = Get-Item $path $attributes = $folder.Attributes If (($attributes -band $FILE_ATTRIBUTE_PINNED) -eq 0) { $folder.Attributes = $folder.Attributes -bor $FILE_ATTRIBUTE_PINNED }