WMIC query to derive absolute share paths on LAN in Windows 10 - batch-file

I'm trying to derive an absolute or full local path from a network path of a folder on a PC drive on LAN using WMIC or similar network tool run from a batch. A few threads devoted to similar tasks on this site when tested don't offer working solution in Win 10.
For example, when running a suggested in one answer query in Win 10 Cmd, I got:
C:\WINDOWS\system32>wmic share where "name='\\Laptop\Data'" get path
Node - OFFICE
ERROR:
Description = Invalid query
C:\WINDOWS\system32>wmic share where "name='Data'" get path
No Instance(s) Available.
I need this result: K:\Data , where K:\ is a hard drive of the remote PC on LAN, and Data is shared folder on that drive.
Can someone suggest a working query & batch for that task? WMIC documentation is way too extensive to derive a working query by trial-and-error without significant experience in using the tool.

wmic share where name='C$' get path
Works here (as only one test doesn't need double quotes). So does
wmic share where "name='C$'" get path
What you posted says you don't have a share called data.
wmic share get /format:list
Shows you what you have.
C:\Users\User>wmic share get
AccessMask AllowMaximum Caption Description InstallDate MaximumAllowed Name Path Status Type
TRUE Remote Admin Remote Admin ADMIN$ C:\Windows OK 2147483648
TRUE Default share Default share C$ C:\ OK 2147483648
TRUE Default share Default share D$ D:\ OK 2147483648
TRUE fred fred C:\Intel OK 0
TRUE Default share Default share G$ G:\ OK 2147483648
TRUE Remote IPC Remote IPC IPC$ OK 2147483651
TRUE TestC TestC C:\ OK 0
As usual wmic /?, wmic share /?, wmic share call /?, wmic share get /?, wmic /format /?.
For remote computers you have to connect to that computer (see wmic /node /?).
wmic /node:127.0.0.1 share get

The following lists the drive letters mapped on the local machine to the (currently connected) remote shares.
C:\etc>for /f "tokens=1-3" %x in ('net use') do #if /i "%x" equ "ok" echo %z = %y
\\laptop\x$ = P:
\\laptop\data = Q:
Following the OP edit (highlight mine):
[+ EDIT for correct net share usage]
I need this result: K:\Data , where K:\ is a hard drive of the remote PC on LAN, and Data is shared folder on that drive.
If you need the K: drive letter assigned on the remote machine to the drive containing the shared directory, then you could run net share remotely using PsExec or similar (provided you have an account with enough rights on the remote machine).
For example, assuming \\laptop is another machine on the LAN, the following will list the share names and (remote) directories on \\laptop.
C:\etc>for /f "tokens=1,2" %u in ('psexec \\laptop cmd /c net share 2^>nul') do #(
for /f "tokens=1,2 delims=:" %x in ("%u %v") do #(
if not "%y"=="" echo "\\laptop\%u" = "%v" ) )
"\\laptop\C$" = "C:\"
"\\laptop\ADMIN$" = "C:\Windows"
"\\laptop\DATA" = "K:\Data"

Suggested in the thread techniques worked with certain additional actions.
When using WMIC, I had to add local admin account to WMI Control Security property. As well, by running GPEDIT.msc enabled "Allow inbound remote administration exceptions" to Firewall rules, despite Firewall was disabled. The proper query is below, processing it's output required a batch file similar in approach to PsExec batch:
wmic /user:[username] /password:[password] /node:"PC-ID" share get
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f "tokens=1,2 skip=1 delims=:" %%u in ('wmic /user:[username] /password:[password] /node:"Laptop" share get') do #(
set "var1=%%u" & set "var2=%%v"
set "var1.1=!var1:~89,-1!" & set "var2=!var2:~0,33!" & set "var1.2=!var1:~97!" & set "var1.3=!var1.1:~0,4!"
if not "!var1.3!"=="IPC$" if not "!var1.1!"=="" echo \\Laptop\!var1.1! = !var1.2!:!var2!)
exit /b
::Output
\\Laptop\ADMIN$ = C:\WINDOWS
\\Laptop\C$ = C:\
\\Laptop\D$ = D:\
\\Laptop\Data = K:\
\\Laptop\K$ = K:\
\\Laptop\Docs = K:\Other\Docs
\\Laptop\print$ = C:\windows\system32\spool\drivers
When using PsExec instead of WMIC, I had to install it first, then add an extra key LocalAccountTokenFilterPolicy in Registry, then modify the command posted earlier:
#echo off
for /f "tokens=1,2" %%u in ('psexec64 -u [username] -p [password] \\Laptop cmd /c net share 2^>nul') do #(
for /f "tokens=1,2 delims=:" %%x in ("%%u %%v") do #(
if not "%%y"=="" echo \\Laptop\%%u = %%v ) )
exit /b
::Output
\\Laptop\C$ = C:\
\\Laptop\D$ = D:\
\\Laptop\print$ = C:\windows\system32\spool\drivers
\\Laptop\K$ = K:\
\\Laptop\ADMIN$ = C:\WINDOWS
\\Laptop\Data = K:\
\\Laptop\Docs = K:\Other\Docs

Related

SC failure command with wildcard

I am trying to write a batch script to configure the recovery options (First failure, second failure, subsequent failure) i.e. SC failure for a custom server installed as a Windows service.
The problem is the Service Name of the Windows service will be different for each installation. The Service Name will be in format ProductName_ServerName_Version where the ProductName and Version will keep changing and ServerName will be constant. So I wanted to find the installed Windows Service and configure the Recovery options via a batch file which I can use for all installations since the ServerName part is constant and I want to lookup using that. I use the below script.
#echo off
set "service=TestSrv"
for /f "tokens=2 delims=: " %%# in ('sc query type^= service^|find /i "SERVICE_NAME:"^|findstr /i /b /c:"SERVICE_NAME: %service%"') do (
set "nservice=%%#"
)
echo %nservice%
sc failure "%nservice%" reset= 60000 actions= restart/60000/restart/60000/restart/60000
Here TestSrv is the ServerName and the above script only returns the Service Name correctly if it is starting with TestSrv. I want a %ServerName% lookup and how to achieve that.
Thanks in Advance.
If you're happy to accept that you will not have any other services within the system which have a name containing _TestSrv_ then you could use WMI to retrieve the service name.
For example, (please change TestSrv on line 1 and complete the last line as necessary):
#Set "ServerName=TestSrv"&Set "nservice="
#For /F Delims^= %%G In ('%__AppDir__%where.exe /R %__AppDir__% mof.xsl 2^>NUL'
)Do #For /F Tokens^=6Delims^=^" %%H In ('%__AppDir__%wbem\WMIC.exe Service^
Where "Name Like '%%[_]%ServerName%[_]%%'" Get Name /Format:"%%G" 2^>NUL'
)Do #Set "nservice=%%H"
#If Not Defined nservice Exit /B 1
#Echo %nservice%
#%__APPDIR__%sc.exe failure "%nservice%" etc…

How to find the name of disk volume, and then perform some action if it is equal to a variable?

I have been banging my head against the wall trying to figure this out. First, to answer what I'm sure will be asked, yes, I need to use a batch script. I'm sure that this is much easier in PowerShell or another language, but it needs to be a Windows Batch Script (CMD).
I am trying to re-design this script to be used on new systems and older systems within our company. The newer systems use Windows Server 2012, while the older systems use Windows Server 2008. Both systems will have 2 hard drives, but the difference between the 2 is the use of the second hard drive. On the older systems, the 2nd drive is used as a backup drive. On the newer system it is not.
In layman's terms, here is what I am looking to do:
IF ANY DISK VOLUME includes "Backup" in it's name (Caption)
SET %buletter% to the Drive Letter
SET other variables
ELSE
SET the backup location to something else
SET other variables
I've been able to pretty easily able to find how to find the name of the disk volume with the following:
FOR /f %%b IN ('wmic volume get DriveLetter^, Label ^| find "%lookfor%"') DO Stuff
But I haven't figured out how to wrap the FOR statement in an IF statement.
Any help is appreciated.
Thanks
Try this:
for /f "usebackq skip=1" %%p in (`wmic volume where "label like '%%Backup%%'" get Driveletter`) do echo Backup Drive is %%p
The only issue - it will give an empty string on a last iteration.
You don't have to use an IF initially,
you can use find and use conditional execution on success && or fail || or
initializing a var and using a for /f to eval the output - and afterwards check if the var is defined.
I'd exclude the first disk by checking for BootVolume in an extended where clause
:: Q:\Test\2019\01\25\SO_54366874.cmd
#Echo off
Set "BackUpDrive="
for /f "usebackq tokens=1,2*" %%A in (`
wmic volume where 'DriveType^="3" AND BootVolume^="FALSE" AND Label like "%%Backup%%"' get DriveLetter^,Label 2^>NUL ^| find ":"
`) Do Set "BackUpDrive=%%A"
If defined BackUpDrive (
Echo Drive with label Backup found: %BackUpDrive%
Rem other commands
) Else (
Echo no drive with label Backup found
Rem other commands
)
Sample output here:
> Q:\Test\2019\01\25\SO_54366874.cmd
Drive with label Backup found: D:
Using the idea from #mirGantrophy of checking the OS Version, this is what I came up with.
SET Version=
FOR /F "skip=1" %%v IN ('wmic os get version') DO IF NOT DEFINED Version set Version=%%v
FOR /F "delims=. tokens=1-3" %%a in ("%Version%") DO (
SET Version.Major=%%a
SET Version.Minor=%%b
SET Version.Build=%%c
)
IF %Version.Major% LSS 10 GOTO Win2008
IF %Version.Major%==10 GOTO Win2012
:Win2008
FOR /F %%p IN ('wmic logicaldisk where "VolumeName='%lookfor%'" get Caption ^| find ":"') DO (
SET buletter=%%p
SET bootdrvltr=C:
)
GOTO SetLocalDrv
:Win2012
SET buloc=C:\Archive
SET bootdrvltr=D:
GOTO SetLocalDrv
:SetLocalDrv
SET localdrv=%bootdrvltr%\Bootdrv

Anyway to reset svn cached auths for a specific repo?

I've been searching all over for this and I'm surprised I haven't found it yet.
I'm using Windows 7.
I've got TortoiseSVN 1.8 with command line tools available but if there is a solution using another client that will work, I'm open to other options.
I'm trying to reset the cached auths for a specific repository on an svn client.
I've have a group of projects (~15) that get built all together. We have setup batch files using the svn command line client to checkout and build the projects which work great on the individual developers machine since the svn client caches their credentials.
However, we are setting up a central build machine for releases (instead of having one person responsible for release builds) and we would like for anyone to be able to login and run a build using their own credentials.
The problem we have is that if we leave the svn client using it's default settings, then anyone logging into the machine will use the previous person's credentials. If we switch the svn client to not cache credentials, then the build process (its all scripted remember) has to prompt for every project which results in the user typing their password ~15 times just to do a build.
We are part of a large company and our svn server houses a lot of different repos for other teams and some developers use multiple repos so I cannot simply clear the cache directory after the build because that would wipe out all cached repos instead of just ours (as far as I can tell, svn only caches by server, not by repo).
Is there any solution I can implement that will prompt for svn credentials on the first project that gets pulled from svn in the batch file, uses those credentials for all projects in the script but then clears the cached credentials for only those projects (or the whole repo) when the script finishes?
I've tried several different method to try and "reset" the credentials for a specific project but I am not having any luck. Even if my script has to go reset them individually, that would be ok.
Someone on another so thread suggested using svn switch on the project and providing a different user via --username when done but that doesn't seem to work on windows (they were using OSX). The next time I run the script, it simply defaults to the last authenticated user.
-edit- added a dumbed down version of the script:
#ECHO OFF
pushd %~dp0
SET SVN=https://domain.com:81/svn/repo
SET TAG=%1
CALL :GET_PROJECT_TAG project1
CALL :GET_PROJECT_TAG project2
CALL :GET_PROJECT_TAG project3
CALL :GET_PROJECT_TAG project4
CALL :GET_PROJECT_TAG project5
CALL :GET_PROJECT_TAG project6
GOTO :END
:GET_PROJECT_TAG
svn export %SVN%/%1/tags/%TAG%/ %TAG%/%1/
EXIT /B
:END
popd
PAUSE
-end edit-
thoughts?
What about having the batch script prompt for credentials if not defined? Use setlocal just below #echo off to make the script forget the credentials on exit. If you'd like to mask the input of the password, it can be done with a PowerShell command.
<NUL set /P "=Password? "
set "psCommand=powershell -command "$p=read-host -AsSecureString;^
$m=[System.Runtime.InteropServices.Marshal];$m::PtrToStringAuto($m::SecureStringToBSTR($p))""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set "pass=%%p"
echo You entered %pass%
Then just reuse %pass% in all svn commands as needed for as long as the script is running. If you're prompted for auth info via a GUI, then might using Subversion for Windows instead of TortoiseSVN solve your problems?
Edit: I feel I should note that it's not unreasonable to expect special characters in passwords that could potentially break your script. Whenever you retrieve the %pass% variable, you should probably do so in the delayed expansion style to prevent characters like ^ and < from being evaluated. But don't enable delayed expansion until retrieval. If delayed expansion is enabled during the input, exclamation marks might be stripped. Do it like this:
#echo off
setlocal
<NUL set /P "=Password? "
set "psCommand=powershell -command "$p=read-host -AsSecureString;^
$m=[System.Runtime.InteropServices.Marshal];$m::PtrToStringAuto($m::SecureStringToBSTR($p))""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set "pass=%%p"
setlocal enabledelayedexpansion
echo You entered !pass!
endlocal
Here are a couple of batch files that I use to temporarily clear the cached credentials. You could easily modify them to suit your particular needs.
:: ClearCachedCredentials.bat
:: 2015-10-30 Kurt Schultz - Tested on Windows 7, 64-bit
:: Move the current TortoiseSVN credential cache files to a backup folder.
:: This allows you to log on to Subversion using a different set of credentials.
:: The original credentials can be restored by running RestoreCachedCredentials.bat
::
:: Alternatively, you can open the individual files in the svn.simple folder using
:: a text editor and look for the user ID that you want to remove from the cache.
:: Remove or delete the file as needed.
#set filePath=\Users\%username%\Application Data\Subversion\auth
#set fileCount=0
#If not exist "C:%filePath%" (
#echo Cannot locate "C:%filePath%"
#echo Do you have Tortoise SVN installed?
) Else (
#C:
#CD "%filePath%"
#for /f %%A in ('dir /b /a-d "svn.simple\*" 2^>nul ^| find /v /c "" ') do #set /a fileCount+=%%A
#Rem When the dir command is issued from the command line, there must be a space between the carat and the pipe e.g. ^ |
#Rem or you will get an error, invalid switch - "v". When inside the "for" command, the space cannot be there.
)
:: I had to move the following section out of the section above in order to test the value of fileCount.
:: When it was inside the Else block above, the value was always 0.
#If %fileCount%==0 (
#echo There were no cached files to backup or clear.
) Else (
#dir svn.simple
#echo.
#echo These credentials will be moved to the backup folder.
#echo.
#echo Press Ctrl-C now to abort or
#pause
)
:: I had to move the following section out of the section above and into its own If condition
:: in order to get the Ctrl-C to work correctly. (The file move did not occur, but the echo
:: statements were still executed.
#If Not %fileCount%==0 (
#If not exist backup (
#md backup
)
#If not exist backup\svn.simple (
#md backup\svn.simple
)
#move svn.simple\*.* backup\svn.simple
#echo.
#echo The TortoiseSVN credentials have been backed up and cleared.
#echo Run RestoreCachedCredentials.bat to restore them.
)
#echo.
#pause
:: RestoreCachedCredentials.bat
:: 2015-10-30 Kurt Schultz - Tested on Windows 7, 64-bit
:: Restore the TortoiseSVN credential cache files from the backup folder.
#set continue=false
#set filePath=\Users\%username%\Application Data\Subversion\auth
#If not exist "C:%filePath%" (
#echo Cannot locate "C:%filePath%"
#echo Do you have Tortoise SVN installed?
) Else (
#C:
#CD "%filePath%"
#If not exist backup\svn.simple (
#Echo The backup directory does not exist. There is nothing to restore.
#Echo You must first use ClearCachedCredentials.bat to create a backup.
) Else (
#echo This will restore the Subversion credentials from your backup folder.
#echo Press Ctrl-C now to abort or
#pause
#set continue=true
)
)
#If %continue%==true (
#copy backup\svn.simple\*.* svn.simple
#echo.
#echo The TortoiseSVN credentials have been restored.
)
#echo.
#pause

batch file goto next xcopy command if windows "Admin" username has changed

I want to be able to run just one instance of xcopy rather than many, from a usb drive to .\admin\desktop on the computer I have plugged it in, however there might be some computers I get on that have the admin username changed to the name of the person. Is there a generic batch namimg convention for the admin user account for windows? If so I'd like to just use that whatever it may be instead of listing everyone's username for every computer and guessing what it might be without looking everytime.
Here is what I have so far, it works well if I know for a fact that the "Admin" user is still labeled "Admin."
#echo off
xcopy "%~dp0M1k_SWPCB\*.*" "C:\Documents and Settings\Admin\Desktop\SWPCB\" /d /s /h /v /c /f /k /y
pause
I tried 'All Users' as well, but in some cases the directory doesn't exist and it will not work. Plus if the computer has multiple users I don't want it on everyones' desktop.
Any help would be much appreciated.
Thanks
All users have a SID identifier and the local admin account always ends with the -500 suffix, so you can get the Admin username by checking the SID's on the Registry:
#Echo OFF
FOR /F "Tokens=*" %%# IN ('Reg Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" ^| FIND "-500"') DO (
FOR /F "Tokens=2,*" %%A IN ('Reg Query "%%#" /v "ProfileImagePath" ^| FIND /V "%%#"') DO (
Echo Admin SID: %%~n#
Echo Admin Folder: %%B
)
)
Pause>NUL&Exit
Output:
Admin SID: S-1-5-21-148789306-3749789949-2179752015-500
Admin Folder: C:\Users\Administrador
Another way to do it is with an VBScript, you can use it in your Batch file and write the Admin name to a textfile, then next you will set a variable with the content of the textfile. (I don't wrote this function):
Set objNetwork = CreateObject("Wscript.Network")
objComputerName = objNetwork.ComputerName
Set objwmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & objComputerName)
qry = "SELECT * FROM Win32_Account where Domain = '" & cstr(objComputerName) & "'"
For Each Admin In objwmi.ExecQuery(qry)
If (Left(Admin.sid, 6) = "S-1-5-" And Right(Admin.sid,4) = "-500") Then MsgBox Admin.name)
Next
PS: Maybe someone will post other solution saying that listing the group names is another choice... but groupnames is not a generic solution 'cause the native language.

Batch To Find All Drive Letters Of Specific Path Mapping

We had a script push out to map a new drive, but net use R: /Delete was not used so the drive is still there and there are incorrect mappings to the next available letter for hundreds of users. I need to delete all incorrect mappings and was hoping there was a batch script that would scan for a specific mapping and then pipe the drive letter.
Set Path = \\Drive\Folder
Set DriveLetter = ?Scan all mapped drives for %Path%?
Net Use %DriveLetter% /Delete
Looking to fill in the blanks here.
Please do not use the PATH variable for your own purposes. It is a reserved variable, and using it for anything other than its intended use can wreak havoc on your batch session.
Here is a solution using WMIC that works. The backslashes must be escaped with another backslash when passed to WMIC. The check for a 2nd token is an artifact of how FOR /F treats the unicode output of WMIC.
#echo off
setlocal enableDelayedExpansion
set "remotePath=\\Drive\Folder"
for /f "usebackq skip=1 tokens=1,2" %%A in (
`wmic netuse where "RemotePath='!remotePath:\=\\!'" get localName 2^>nul`
) do if "%%B" neq "" <nul net use %%A /delete >nul 2>&1 || net use %%A /delete
I'm not sure what is going on, but the first attempt to delete the mapped drive fails with the following message: "There are open files and/or incomplete directory searches pending on the connection to n:.". The second attempt succeeds.
net use will show drive mappings (connected or not)
example output:
New connections will be remembered.
Status Local Remote Network
-------------------------------------------------------------------------------
Disconnected Q: \\Server1\Drive
Microsoft Windows Network
OK S: \\Server2\Drive2
Microsoft Windows Network
The command completed successfully.
looking at this output, the 2nd column, gives us the drive letter, and the 3rd gives us the path. putting this into a for /f loop to check the path, and if it matches delete the drive letter in the 2nd part
for /f "tokens=2,3" %%a in ('net use') do if .%%b==.\\Server\DriveCaseSensitive net use %%a /Delete
This means that it will also detect and remove mappings if the drive has been mapped multiple times

Resources