I have a Powershell script on my windows machine that needs to access data from a USB drive. It reads a file from the USB stick and does its thing. I need to do this over many machines. The problem is that the USB drive can appear under different drive letters, depending on the machine I insert the stick into. My USB drive is called "USBData". Is there a way to reliably access the USB drive using its name rather than its drive letter?
$driveletter = (Get-Volume -FileSystemLabel "USBData").DriveLetter
echo "${driveletter}:\"
You can do a:
(Get-WMIObject Win32_Volume | ? { $_.Label -eq 'USBData' }).DriveLetter
to get the Drive and then execute relative to it. Something like:
$USBDrive = (Get-WMIObject Win32_Volume | ? { $_.Label -eq 'USBData' }).DriveLetter
$ProcessFullPath = "$USBDrive\Executable.exe"
Start-Process $ProcessFullPath
Related
I have two computers: A and B. I'm trying to automate some CI\CD tasks, and my task is to start some process on B remotely, from A. The .exe file itself is on the R drive, which is a local network drive. So I do this:
# here $cred has encrypted credentials, but it is off topic...
Invoke-Command -ComputerName B -Credential $cred -ScriptBlock {
R:\WebClient\Platform\UP_110\Proc.exe
}
So apparently this would be the same thing as typing R:\WebClient\Platform\UP_110\Proc.exe on B's PowerShell and hitting Enter.
Now the problem is that I get this error when running the above code on A:
The term 'R:\WebClient\Platform\UP_110\Proc.exe' is not recognized as the name of a cmdlet, function, sc
ript file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is corr
ect and try again.
+ CategoryInfo : ObjectNotFound: (R:\WebClient\Pl...IMS.UP.Host.exe:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : B
Apparently it says that there is no such file as R:\WebClient\Platform\UP_110\Proc.exe on my B computer. But that is not true. I do have it:
As a matter of a fact, I have this R drive both on A and B.
The code works fine if I move the .exe to any directory under the C drive (which is the system disk for me), but not for R.
Now even funnier is that I can run R:\WebClient\Platform\UP_110\Proc.exe on A and B manually. And it works.
So what's the issue here I'm facing? Thanks.
PowerShell Remoting can only access drives by default that are mapped within the system context. Most commonly, this will be letter drives based on attached hardware (whether this be USB, SATA, SCSI, etc.).
Drives mapped in the user context, such as remote drives, are not mapped because a full logon does not occur the same way as if you log in locally. There are two workarounds you have at your disposal:
Use the UNC path when accessing files over an SMB/CIFS share (e.g. \\server.domain.tld\ShareName\Path\To\Folder\Or\file.ext
Map the drive within the ScriptBlock passed to Invoke-Command using New-PSDrive:
# Single letter drive name
New-PSDrive -Name "R" -PSProvider FileSystem -Root "\\server.domain.tld\ShareName"
Get-ChildItem R:
# More descriptive drive name
New-PSDrive -Name "RemoteDrive" -PSProvider FileSystem -Root "\\server.domain.tld\ShareName"
Get-ChildItem RemoteDrive:
Three things to note:
Get-ChildItem in the example above is to show that listing the contents of the new drives should show the files you expect to see at the remote directory. This can be omitted once you are sure it works for you.
Additionally, using a longer drive name is a PowerShell feature and does not mean that you can map shared folders as a drive from within File Explorer with more than a single character.
You may run into the double hop issue trying to map to a remote drive this way, if you are attempting to use the same credential you initiated Invoke-Command with. Solving it properly is beyond the scope of Stack Overflow as this is a major architectural consideration for Active Directory.
However, you can work around it by building the credential object and passing it toNew-PSDrive from within the ScriptBlock, or running Invoke-Command with-Authentication CredSSP if your organization does not block it (many do).
I want to list all my disks with a .bat file to check if a network disk is connected or not.
I've made the next .bat file that works and shows me the physical and logial disks.
#echo off
wmic logicaldisk get caption,drivetype,providername
pause
exit
The question is: How do I check if it's connected or not? It possible to autoconnect in case the mapped disk is disconnected?
Thanks!
You can modify the pattern in the sample below to return Connected or Disconnected mapped drives (or remove the piped portion all together to return all connections). As for reconnecting the drives, if they're disconnected, doesn't that mean its a network issue, since windows automatically reconnects them when the connection is available?
Batch Script (CMD):
wmic netuse list brief | find "Connected"
Powershell:
wmic netuse list brief | Select-String -Pattern "Connected"
I would like to obtain by a command prompt a list of all USB devices connected to my computer (O.S. Windows 10). I've googled to find such a command, but all results seems useless to me or worse workless. Does anybody know how can I do that?
Thank you
You can use the wmic command:
wmic path CIM_LogicalDevice where "Description like 'USB%'" get /value
With powershell, you can use the command :
Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -match '^USB' }
You could use wmic command:
wmic logicaldisk where drivetype=2 get <DeviceID, VolumeName, Description, ...>
Drivetype 2 indicates that its a removable disk.
pnputil /enum-devices /connected /class USB
This requires Windows 10 1903 or higher. List of possible flags
you can download USBview and get all the information you need. Along with the list of devices, it will also show you the configuration of each device.
I am use this command for finding hard disk in formation "wmic diskdrive" but i insert a external device like hard disk or pan drive, this command is provide information of external hard disk or pan drive. so how can find internal hard disk information where system window installed.
It is off topic here , though you can get the info using following cmd
wmic logicaldisk
or ,
diskpart then list volume
The PowerShell way is:
PS C:\> $Disk = Get-WmiObject -Class Win32_logicaldisk -Filter "DeviceID = 'C:'"
PS C:\> $DiskPartition = $Disk.GetRelated('Win32_DiskPartition')
PS C:\> $DiskDrive = $DiskPartition.GetRelated('Win32_DiskDrive')
PS C:\> $DiskDrive.Size
1024203640320
This is nicely explained here.
But the original question was about how to do this with CMD.
C:\>wmic diskdrive get model,name,size
Model Name Size
SAMSUNG MZVLB1T0HALR-000L7 \\.\PHYSICALDRIVE0 1024203640320
Generic- SD/MMC USB Device \\.\PHYSICALDRIVE1
Given a choice, I prefer to use the PowerShell method, starting from the drive letter and working up to the physical disk. It's rather verbose but it gives a unique answer, and requires no knowledge of the system. (Some devices have many physical disks and it can get confusing.)
"find internal hard disk information where system window installed."
wmic logicaldisk where caption="%systemdrive%" get /value
Note: logicaldisk is a partition on an physical drive (the only one, if you are lucky, but there may be more partitions on the same physical drive)
I have a virtual hard disk .vhd file that I would like to backup on a daily basis by clicking on a shortcut on my Windows Vista laptop. I wrote a half-hazard batch script file (BACKUP.BAT) which accomplishes the job, where it open the cmd window and copies the file to the flash drive, but I would like to mimic (macro) the way the copying is displayed when you manually drag and drop the file into the flash drive in my computer. Another problem is that depending on what computer this is done, the USB flash drive could have drive E: assigned to it (WinXP) and on other computers (Vista/7) it could be drive F:. (There doesnt seem to be a way to statically assign a fixed drive letter to the USB flash drive when it is inserted into the USB port.)
I would set the volume name of the disc, and examine all connected drives and find the drive with that volume name. Here's how I do it in PowerShell:
param([parameter(mandatory=$true)]$VolumeName,
[parameter(mandatory=$true)]$SrcDir)
# find connected backup drive:
$backupDrive = $null
get-wmiobject win32_logicaldisk | % {
if ($_.VolumeName -eq $VolumeName) {
$backupDrive = $_.DeviceID
}
}
if ($backupDrive -eq $null) {
throw "$VolumeName drive not found!"
}
# mirror
$backupPath = $backupDrive + "\"
& robocopy.exe $SrcDir $backupPath /MIR /Z
This code gets the last ready to use removable drive (e.g. an USB drive just plugged-in):
$drives = [System.IO.DriveInfo]::GetDrives()
$r = $drives | Where-Object { $_.DriveType -eq 'Removable' -and $_.IsReady }
if ($r) {
return #($r)[-1]
}
throw "No removable drives found."
This way does not require the fixed volume name to be pre-set. We can use different USB drives without knowing/setting their names.
UPDATE
To complete drag-and-drop part of the task you can do this.
Create the PowerShell script (use Notepad, for example) C:\TEMP_110628_041140\Copy-ToRemovableDrive.ps1 (the path is up to you):
param($Source)
$drives = [System.IO.DriveInfo]::GetDrives()
$r = $drives | Where-Object { $_.DriveType -eq 'Removable' -and $_.IsReady }
if (!$r) {
throw "No removable drives found."
}
$drive = #($r)[-1]
Copy-Item -LiteralPath $Source -Destination $drive.Name -Force -Recurse
Create the file Copy-ToRemovableDrive.bat (for example on your desktop), it uses the PowerShell script:
powershell -file C:\TEMP\_110628_041140\Copy-ToRemovableDrive.ps1 %1
Now you can plug your USB drive and drag a file to the Copy-ToRemovableDrive.bat icon at your desktop. This should copy the dragged file to the just plugged USB drive.