Skip to content

Instantly share code, notes, and snippets.

@cveld
Last active June 23, 2024 20:19
Show Gist options
  • Save cveld/8fa339306f8504095815 to your computer and use it in GitHub Desktop.
Save cveld/8fa339306f8504095815 to your computer and use it in GitHub Desktop.
PowerShell that crawls your Android usb folder structure

Crawl your Android device attached via usb with PowerShell

The PowerShell script Crawl_Android.ps1 is capable of crawling your Android device when it is attached via usb. Just execute Crawl_Android.ps1 and select the device from the menu.

Limited file details

What I found out is that the Shell Namespace API does not provide a lot of details of the file. It is limited to only a couple of fields that are relevant for the Windows Explorer GUI. Strangely, a byte-oriented filesize field is not part of it. It only contains a summarized version, e.g. 4 kB or 10 MB. After futher investigation, I noticed that Windows Explorer has to make a local temporary copy to get all the details in order to populate the information pane. That's why most operations are so slow!

# http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/26/use-powershell-to-work-with-windows-explorer.aspx
$o = New-Object -com Shell.Application
$folder = $o.NameSpace(0x11)
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb774096(v=vs.85).aspx
# ShellSpecialFolderConstants.ssfDRIVES == 0x11
$items = $folder.Items()
for ($i= 0; $i -lt $items.Count; $i++) {
write-output ([string]$i + ": " + $items.Item($i).Name)
}
$choice = Read-Host "Make your choice"
$android = $items.Item([int]$choice)
$root = $android.GetFolder()
# FolderItem versus FolderItems
$maxdepth = Read-Host "Max depth"
Function Write-Items($item, $depth, $maxdepth) {
if ($depth -ge $maxdepth) {
return;
}
$indent = ""
for ($i = 0; $i -lt $depth; $i++) {
$indent += " ";
}
#write-output ($indent + "Name: " + $item.name)
if ($item.Title) {
$hash = @{
Name = $item.Title
Size = $null #$item.ParentFolder.GetDetailsOf($item, 2)
Modified = $null #$item.ParentFolder.GetDetailsOf($item, 3)
Parent = $item.ParentFolder.Title
Level = $depth
}
$Object = New-Object PSObject -Property $hash
write-output $object
} else {
$hash = @{
Name = $item.Name
Size = $item.Parent.GetDetailsOf($item, 2)
Modified = $item.Parent.GetDetailsOf($item, 3)
Parent = $item.Parent.Title
Level = $depth
}
$Object = New-Object PSObject -Property $hash
Write-Output $object
}
if ($item.Count -gt 0) {
# $item is a folder with its own items
for ($i = 0; $i -lt $item.Count) {
$item2 = $item.item($i)
Write-Items $item2 $depth+1 $maxdepth
}
}
else {
if ($item.Items) {
$items = $item.Items()
if ($items.Count -gt 0) {
foreach ($i in $items) {
if ($i.IsFolder) {
$folder = $i.GetFolder()
Write-Items $folder ($depth+1) $maxdepth
}
else {
Write-Items $i ($depth+1) $maxdepth
}
}
}
}
else {
# .Count == 0 and no Items present
# we don't need to do anything further here
}
}
}
Write-Items $root 0 $maxdepth | Out-GridView
@mgbeda
Copy link

mgbeda commented Jun 23, 2024

Thank you! This works. I did have to change $android.GetFolder() to $android.GetFolder in two places. Thanks to you both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment