Access MTP storage with System.IO from PowerShell

Viewed 6441

I'm trying to access MTP device storage to automate file copy, backup, etc. If Windows Explorer is able to open and browse Android device Internal Storage and connected SD card, how can I access these storages with PowerShell?

I've found a lots of hints, such as "get device ID and use WMI"

What is the way the Windows Explorer uses to open and browse especialy Android's storages?

Is it possible to use some System.IO Class like here?

$drives = [System.IO.DriveInfo]::GetDrives()
$r = $drives | Where-Object { $_.DriveType -eq 'Removable' -and $_.IsReady }
if ($r) {
    return @($r)[-1]
}

I'm able to access and browse content of local MTP (android) device with this:

$WIAdialog = New-Object -ComObject “WIA.CommonDialog”
$Device = $WIAdialog.ShowSelectDevice()
$Device = $WIAdialog.ShowAcquireImage()
$Device = $WIAdialog.ShowAcquisitionWizard()
$Device = $WIAdialog.ShowDeviceProperties()
$Device = $WIAdialog.ShowItemProperties()
$Device = $WIAdialog.ShowPhotoPrintingWizard()
$Device = $WIAdialog.ShowSelectItems()
$Device = $WIAdialog.ShowTransfer()

But this code is loading information about stored pictures which is too slow even at local computer. Is it possible to avoid loading info about pictures to speed up loading and accessing remotely connected devices?

Thanks in advance for any information and hints!

2 Answers
Function fn_PhoneFolder {
    Param($PhoneName, $PhoneFolder)

    Write-Host "Searching....$($PhoneName)" -ForegroundColor Green

    $Shell = new-object -com Shell.Application
    $ShellItem = $Shell.NameSpace(17).self #17 = My Computer (https://docs.microsoft.com/en-gb/windows/win32/api/shldisp/ne-shldisp-shellspecialfolderconstants?redirectedfrom=MSDN)
    $Phone = $ShellItem.GetFolder.items() | where { $_.name -eq $PhoneName }

    $FolderParts = @( $PhoneFolder.Split([system.io.path]::DirectorySeparatorChar) )

    $PhonePath = $Phone
        ForEach ($Part in $FolderParts) {
            If ($Part) {
                $PhonePath = $PhonePath.GetFolder.items() | where { $_.Name -eq $Part }
                }
            }

    $ReturnFiles = New-Object System.Collections.Generic.List[System.Object]

    $Files =  @($PhonePath.GetFolder.items())

    $Files

    ForEach ($File in $Files) {
        $TempFiles = @{}
        $TempFiles.Name = $File.Name
        $TempFiles.Path = $File.Path
        $TempFilesObject = New-Object PSobject -Property $TempFiles
        $ReturnFiles.Add($TempFilesObject)
        }

    Return $ReturnFiles

}

$MyPhoneFiles = fn_PhoneFolder -PhoneName "X19" -PhoneFolder "Internal shared storage\WhatsApp\Media\WhatsApp Images\Sent"

Change PhoneName and PhoneFolder on the last line to match your Phone Name as displayed in My Computer. This function will pull back an array of all files in the folder selected. Thanks to https://blog.daiyanyingyu.uk/2018/03/20/powershell-mtp/ for the idea of searching through the shell folders to find the phone.

Related