dot net command: net use - How to only get Alphabet and pathname? - cmd

When I do a "net use" on my command prompt, it will display the following:
New connections will be remembered.
Status Local Remote Network
-------------------------------------------------------------------------------
OK W: \\hfs2\ATS\Novell Profile Backup\wk\one\two\three\four\five\six\seven\eight\nine\ten\eleven\twelve\thirteen
Microsoft Windows Network
OK X: \\hfs2\ATS\Novell Profile Backup\wk\one\two\three\four\five\six\seven\eight\nine\ten
Microsoft Windows Network
OK Y: \\hfs2\ATS\Novell Profile Backup
Microsoft Windows Network
Unavailable Z: \\hfs2\ATS Microsoft Windows Network
The command completed successfully.
How do I extract ONLY get the drive alphabet and pathname?
W:
\\hfs2\ATS\Novell Profile Backup\wk\one\two\three\four\five\six\seven\eight\nine\ten\eleven\twelve\thirteen
X:
\\hfs2\ATS\Novell Profile Backup\wk\one\two\three\four\five\six\seven\eight\nine\ten
Y:
\\hfs2\ATS\Novell Profile Backup
Z:
\\hfs2\ATS

EDIT
WMIC does not require administrator rights
It does require rights for what you are trying to do. You can't use it to do admin things if not an admin.
It also requires an administrator to run it once on a system to set it up.
From Help
User Account Control
Under UAC, accounts in the local Administrators group have two access tokens, one with standard user privileges and one with administrator privileges. Because of UAC access token filtering, a script is normally run under the standard user token, unless it is run "as an Administrator" in elevated privilege mode. Not all scripts required administrative privileges.
Scripts cannot determine programmatically whether they are running under a standard user security token or an Administrator token. The script may fail with an access denied error. If the script requires administrator privileges, then it must be run in the elevated mode. Access to WMI namespaces differs depending on whether the script is run in elevated mode. Some WMI operations, such as getting data or executing most methods, do not require that the account run as an administrator. For more information about default access permissions, see Access to WMI Namespaces and Executing Privileged Operations.
Wmic
The first time you run Wmic after system installation, it must be run from an elevated command prompt. The elevated mode may not be required for subsequent executions of Wmic unless the WMI operations require administrator privilege.
Use WMIC
wmic netuse get /format:list
gives you what's available.
Use something like
wmic netuse get remotepath, localname /format:list
To put the output in a file or on the clipboard.
WMIC specific switch
/output or /append
eg
wmic /node:"#%userprofile%\desktop\ComputerName.txt" /output:"%userprofile%\desktop\EventLog.html" /failfast:on PATH Win32_NTLogEvent where (EventIDentifier=42 or eventidentifier=1003) get /format:hform
(/node is a list of IP addresses and/or computer names of computers to run the command against, one IP address or computer name per line)
General Command Prompt File Redirection
Appending >filename.ext (or >>filename.ext to append to a file)to a command writes the output to the file rather than the screen.
wmic baseboard get product,Manufacturer,model,partnumber>MotherboardPartNum.txt
General Command Prompt Piping
Appending |command sends the output to a command rather than the screen. The usefull commands that output is sent to are
find or findstr (finds and filters text)
sort (sorts the output)
more (displays output to screen one page at a time)
clip (puts output onto the clipboard)
null (makes the data disappear for good - used for unwanted error messages)
wmic baseboard get product,Manufacturer,model,partnumber|clip
Combining Piping and Redirection
So we can combine them. To send the list to a file on the desktop in reversed sort order (z to a) with blank lines removed.
wmic service get name,displayname /format:list|findstr .|sort /r>"%userprofile%\desktop\services_reversed.txt"
WMIC Output Options
The output options are
/Format:list (a list - use notepad to view)
/format:table (a table - use notepad to view)
/format:hform (an html list - name the file's extension .html so IE will show)
/format:htable (an html table - name the file's extension .html so IE will show)
/format:csv (comma seperated variable - used for importing data into other programs such as excel)
also value, mof, rawxml, and xml.
So,
sort /?
find /?
findstr /?
more /?
clip /?

There are some problems in the output of net use
The Status field can hold information or be empty.
The Network field can have multiple values depending of network mapping. In my case i have "Microsoft Windows Network" and "Netware Services". So, there is no direct substitution.
The Network field can be in the same line that the Remote field or can be on the next line, and as the Remote field may include spaces, checking the character at the column limit position is not reliable. It is necessary to delay the check until the next line is readed to determine if it contains remote data.
So, not a one liner to handle it
#echo off
setlocal enableextensions disabledelayedexpansion
set "drive="
for /f "skip=6 tokens=1,* delims=\" %%a in ('net use') do (
if defined drive (
setlocal enabledelayedexpansion
if "%%b"=="" (
echo !drive! !networkPath!
) else (
echo !drive! !networkPath:~0,26!
)
endlocal
set "drive="
)
if not "%%b"=="" for /f "tokens=2" %%c in ("x%%a") do (
set "drive=%%c"
set "networkPath=\\%%b"
)
)
%%a loop will read the lines from net use and split them using a backslash as delimiter. This will allow us to determine if the line contains or not a network path (if there is no second token, the line did not contain a backslash).
As we are delaying the output of the information in one line until the next is readed (to determine if the remote path continues in the Network column), the first operation inside the for loop is to determine if we have data pending from previous loop. If there is data, depending on the content of the current line we select what to output.
Once the data is echoed, if the current line contains network information, it is saved for later output.
This is the faster solution, but there are two alternatives that require less code:
multiple net use commands
#echo off
setlocal enableextensions disabledelayedexpansion
rem For each line in the output of the net use that includes a drive letter
for /f "delims=" %%a in ('net use^|find ":"') do (
rem Retrieve the drive letter from the line
for /f "tokens=2" %%b in ("x%%a") do (
rem Run a net use with the drive letter and output the drive and the path
for /f "tokens=1,* delims=\" %%c in ('net use %%b') do if not "%%d"=="" echo(%%b \\%%d
)
)
Less code, but as multiple net use commands are executed, it is slower
Use WMIC
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=2,3 delims=," %%a in (
'wmic netuse get LocalName^, RemoteName^, Status /format:csv ^| find ":"'
) do echo(%%a %%b
Less code, but in this case, adminitrator righs are required to run the command

I might be a little late but this helped me
WMIC NETUSE GET LocalName, RemotePath /FORMAT:TABLE | FIND /i ":"

Related

Check and obtain Server access using Windows Batch File

First of all I'm a complete noob to Batch scripting and networking, with that being said, Here is what I'm trying to accomplish.
I want to check if the server has provided this batch file executing pc to access it, if not create access to it. (many different pc's run this batch file)
This what I came up with for now in my batch file.
net use * \\ip\My_WebApp /Persistent:yes /user:Username Password
Exit
This batch file command create access to the server just fine but It creates a new access connection every time this file get executed. Which is not needed and might crash the server load.
How can I check if the Server already has provided the access, Only if not, execute the above command in a batch file. my logic like like....
boolean status = check_server_accessibility()
if(!status){
net use * \\ip\My_WebApp /Persistent:yes /user:Username Password
}
Exit
Appreciate any help, Thank you so much for your time.
You should only ever need to perform the task once, which suggests that a scripted solution isn't needed, (persistent means that!). I would assume that the following may be sufficient:
#Set "MyMap=\\ip\My_WebApp"
#%__AppDir__%wbem\WMIC.exe LogicalDisk Where "DriveType='4'" Get ProviderPath 2>NUL | %__AppDir__%findstr.exe /R /I "%MyMap:\=\\%\>" 1>NUL && GoTo :EOF
#%__AppDir__%net.exe Use * "%MyMap%" /Persistent:Yes /User:Username Password
Alternatively, if you needed to know which drive letter is currently assigned to it, then use a for-loop to retrieve the data:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Call :MapChk "\\ip\My_WebApp"
GoTo :EOF
:MapChk
Set "MyMap=%~1"
Set "MyDrv="
For /F "Skip=1 Delims=:" %%G In (
'%__AppDir__%wbem\WMIC.exe LogicalDisk Where "DriveType='4' And ProviderPath='%MyMap:\=\\%'" Get DeviceID 2^>NUL'
) Do For %%H In (%%G) Do Set "MyDrv=%%G:"
If Defined MyDrv (
Echo %MyMap% is already mapped to drive %MyDrv%.
%__AppDir__%timeout.exe /T 5 /NoBreak >NUL
GoTo :EOF
)
%__AppDir__%net.exe Use * "%MyMap%" /Persistent:Yes /User:Username Password
I've made this one into a callable label, so that you can more easily extend it for other mappings too, e.g. before the GoTo :EOF, (line 6), Call :MapChk "\\Server\My Share".
Note: These solutions are untested, I do not use a PC and have no mapped network locations to test them against. Please let me know if I have made a mistake somewhere.

Get logon username in elevated script with standard user account

In my batch script run within Windows 7, I have several IF clauses like:
IF "%USERNAME%"=="foo" GOTO bar
Unfortunately, when I run this batch script elevated with "Run as administrator" from the Context Menu, the %USERNAME% is always the administrator's username, not the username of the current active logon user.
The same applies to whoami in an elevated batch script.
QUERY USER gives me a list of all users currently logged on, not merely the one user I am looking for.
A standard user account, unlike an administrator account that can elevate from user group token to administrator group token while keeping the same user environment, actually loads the administrator account environment when "Run as administrator" is selected.
Is there a way to get the current active logon username instead of the administrators username?
WMIC ComputerSystem Get UserName
#echo off
setlocal
rem Get logon username without the leading "computername\" string.
set "user="
for /f "skip=1 tokens=1,* delims=\" %%A in (
'wmic computersystem get username ^|findstr /r /v "^$"'
) do for %%C in (%%~B) do if not defined user set "user=%%~C"
echo "%user%"
pause
Using the for /f option skip=1, as the 1st line is the UserName header that is not wanted. Delimit by \ as the value will be like computername\username and get the remainder in the 2nd token. Pipe to findstr to ignore empty lines. 2nd for loop will get the first value free of whitespace characters.
Piping wmic output to powershell to cleanup the output tests better than piping to findstr, and the use of a 2nd for loop is not needed.
#echo off
setlocal
rem Get logon username without the leading "computername\" string.
set "user="
for /f "skip=1 tokens=1,* delims=\" %%A in ('
wmic computersystem get username ^|
powershell -noprofile -command "$input.trim()"
') do set "user=%%~B"
echo "%user%"
pause
Use command /? for more help. Most commands in the code will display help with the /? argument at a Command Prompt.
Query User alias QUser
#echo off
setlocal
rem Get logon username.
set "user="
for /f %%A in ('quser^|findstr /b /c:">"') do set "user=%%~A"
if defined user if "%user:~0,1%" == ">" set "user=%user:~1%"
echo "%user%"
pause
The leading > in quser (an alias for query user) indicates the currently logged on username, not the administrator's username.
Use %user% instead of %username% where needed.
Notes:
Due to for /f loop getting username from the default option of token=1, if username contains a space or tab, then this will get only the characters that precede the space or tab.
On a 64 bit OS, quser.exe exists in System32, not in SysWOW64. A 32 bit cmd.exe on a 64 bit OS may not be recognized as a command.
References:
query user
Query User / QUSER

How to check if current drive is on a local disk (cmd)?

To get the drive the current batch resides in is easy using
set batchdrive=%~d0
But how is it possible to check if %batchdrive% is on a local drive and not on a (mapped) network share?
Checking for %SYSTEMDRIVE% or a fixed list "C:" "D:" ... is not reliable.
To check whether a drive (%~d0) is a local one, you could use a wmic query:
wmic LogicalDisk where(DeviceID="%~d0" AND DriveType=3) get Description,DeviceID,DriveType
Given that %~d0 expands to the local drive C:, the output looks like:
Description DeviceID DriveType
Local Fixed Disk C: 3
In case %~d0 is a network drive Z:, the error output is:
No Instance(s) Available.
Unfortunately, wmic does not set the ErrorLevel in case of no matches, but the above message is returned at the STDERR stream rather than the STDOUT stream, so we can apply redirection to discard STDOUT (in case the drive matches; so the get query is omitted as it is not used anyway) and redirect STDERR to STDOUT instead (so the error message is returned at STDOUT in case):
2>&1 > nul wmic LogicalDisk where (DeviceID="%~d0" AND DriveType=3)
Hence the command line returns nothing in case %~d0 is a local drive, but something otherwise. Now let us capture the (redirected) STDOUT by a for /F loop:
for /F "delims=" %%L in ('
2^>^&1 ^> nul wmic LogicalDisk where ^(DeviceID^="%~d0" AND DriveType^=3^)
') do echo Drive "%~d0" is not local!
So if %~d0 points to a local drive, the body of for /F is not executed, but otherwise it is.
According to this resource, WMI and therefore the wmic command line tool is available since Windows XP (Prof.) onward; it was not available on Windows XP Home though. wmic does not require administrative privileges. The Win32_LogicalDisk class is available since availability of WMI. Reference the following resources for more information about WMI/wmic: Windows Management Instrumentation: Frequently Asked Questions and WMIC - Take Command-line Control over WMI.
The first thing to check is if batchdrive is an unmapped network share (this happens if you start the batch file outside of cmd.exe, for example via double click or via a system call):
if "%batchdrive%" == "\\" set nshare=1
The second thing is to check if batchdrive is in the list of network shares. These are shown with net use, which output is similar to
status local remote network
-------------------------------------------------------------------
OK D: \\computer1\share1 Microsoft Windows Network
OK E: \\computer1\share2 Microsoft Windows Network
disconnected F: \\computer2\share Microsoft Windows Network
Command executed successfully.
Therefore we filter the output for all lines that looks like a disk drive with findstr /r /c:" [A-Z]: " and took the second part of the output via for /f "tokens=2".
Complete snipped (working on WinXP and above):
if "%~d0" == "\\" (
set nshare=1
) else (
set nshare=0
for /f "tokens=2" %%a in ('net use ^| findstr /r /c:" [A-Z]: "') do (
if "%%a" == "%~d0" set nshare=1
)
)
Comments for possible issues requested :-)

Check either if user has access to UNC path or is in an AD group from command prompt

I'm writing a batch file to map two drives for a given account if the user has access. I don't want an error message to pop up if the user doesn't have access, I'd like it to fail silently and move on. All accounts have access to the first drive, so that one's fine, but only some users can access the second.
This is the command that actually maps the drive, variables are self-explanatory:
net use h: \\ipaddress\share "%password%" /user:%usern% /persistent:no > nul 2> nul
If I run this regardless of whether the user has access, a separate window opens with an error stating the user doesn't have access. net use does not set errorlevel if the user doesn't have access--it maps the drive but Explorer throws an error when trying to open it. The first drive checks if the user's credentials are entered correctly; errorlevel is set if credentials are incorrect.
The domain controller is not running AD Web Services, and the computer running the script does not have RSAT installed.
How can I check if a given user (credentials provided by prompts in the batch file) has access to a drive or is a member of an AD group so that I can determine whether to map a drive for that user inside a batch file?
I was able to figure this out. First, get the distinguished name of the user account and store it in a variable. dsquery user is used to accomplish this.
for /f "tokens=* USEBACKQ" %%f in (`dsquery user -samid %usern%`) do (
set DN=%%f
)
Next, use dsget user to list the groups a user is a member of and pipe it to a file.
dsget user %DN% -memberof > tmp.txt
Next, search the file for the name of the group using findstr. findstr sets errorlevel to 1 if the string is not found, and to 0 if it is found. The output is piped to nul to prevent anything from showing in the prompt.
findstr /c:"H DRIVE MAPPING" tmp.txt > nul 2> nul
Since errorlevel is set, this is possible. del also sets errorlevel, so the check for the value of errorlevel must be done before deleting the file.
if errorlevel 1 (
echo not in group
del tmp.txt
exit
)
echo in group
del tmp.txt

Execute Batch File With Different Process Name

I have 6 different batch scripts that I am running together at the same time. The problem is, it is difficult to differentiate between them in the Windows Task Manager because the process is always just cmd.exe I was wondering if there was a way to change the process name for a batch script to something else so that each script would be more identifiable.
I have done a lot of research on this topic so far, and the only lead that I have is creating a copy of cmd.exe in system32 that has a different name, one of my choosing. The problem is, I am not sure how I would get my bash script to use this new executable with a different name, rather than the default cmd.exe
Requirement: Must use only built in Windows functionality. I do not want to install any other programs if possible.
You can do it with something like the subroutine below. The reason for the first goto is so that you don't fall into the subroutine when you are done. I incorporate another FOR loop to iterate through a list of filenames to check. Let's get this working first.
Your existing bat file goes here
CALL :IsitRunning "SomeFileName"
The rest of your existing bat file goes here
GOTO :eof
:IsitRunning
REM 1=Filename
FOR /F "delims=" %%A in ('WMIC PROCESS WHERE NAME^='CMD.EXE' LIST FULL ^| FINDSTR /I "%~1" ^| FINDSTR /I /V WMIC') DO ECHO(%~1 is running
GOTO :eof
Or you can run this command from a CMD prompt.
wmic process WHERE NAME='cmd.exe' list full | findstr /i "SomeFileName.bat"
You can see command line in Task Manager, turn it on View menu - Choose Columns.
If you want to change process name you have to change the process. So your approach is only way.

Resources