Mapping Drive to an unknown share name? - batch-file

I'm trying to create a batch file that can look through contents of network shares to find a specific named directory and subdirectory and then map a drive to the share that contains these. Problem being that, whilst the contents of the share have these folders in them to identify that this is the correct share, the share name itself may be different in different setups, so I can't just use the share name in the script.
In other words
\\server\share\sims\setups
the sims and setups directories will ALWAYS exist in the share, but the share name is the thing that can be different. The server name will already exist in the batch file as it is set by using the set /p command to prompt the user for the servers ip.
i have looked at the find and the forfiles commands but these seem to only work to search locally and not on network paths.
Thanks

As indicated by foxidrive you can use the net view command to list shares of a server.
The for command is able to iterate over output from commands. Combining these in the following rough commandline does map a drive for me if a certain folder/file is present.
for /F %a in ('net view \\srv') do if exist "\\srv\%a\sims\setup" net use z: \\srv\%a
(don't forget to change %a to %%a if you use this line in a command-script)
The net view does output some noise but that doesn't screw the result. You could add some extra handling to only handle shares after the '-----' line is received.
How does this work?
net view \\server outputs the following:
Shared resources at \\server
Awesome server
Share name Type Used as Comment
-----------------------------------------------------------------------------
Configuration Disk System Configuration
Download Disk Download Share (Full Access)
Public Disk Public Share (Full Access)
Blah Disk Blah share (Full Access)
The command completed successfully.
The for /f command parses each line up to the next space. From the FOR /?
FOR /F ["options"] %variable IN (`command`) DO command [command-parameters]
...you can use the FOR /F command to parse the output of a
command. You do this by making the file-set between the
parenthesis a back quoted string. It will be treated as a command
line, which is passed to a child CMD.EXE and the output is captured
into memory and parsed as if it was a file.
Using that technique would echo the following result if run on net view \\server:
Shared
Network
Share
-----------------------------------------------------------------------------
Configuration
Download
Public
Blah
The
The EXIST operator checks if a file/directory exists. By concatenating the servername, share and the expected folder you can find out if that folder does excist on that share.
As I said the first 4 lines and the last line are noise and should be ignored but they don't hurt too much in this scenario.

Related

Is there an API which exposes the paths searched by the start command?

What paths are searched by start? Is this path list queryable via WMI, the registry, WSH shell folder constants, .NET methods, or any other Windows API?
In a cmd console, the start command is sort of magic. Say your default web browser is Firefox. You also have Chrome and Opera installed, but they are neither set as default, nor associated with any file types, nor in your %PATH%. Considering the following example:
start "" opera https://stackoverflow.com
... why does that work?
The reason this matters is that, for all the start command's strengths, it is still perilous to retrieve an application's PID or window handle when that application was launched with start. In a cmd environment I'd prefer to use wmic process call create in a for /F loop to capture the PID. So is there a way I can teach wmic process call create to launch "opera" or "iexplore" or "outlook" or "winword" or other applications as start can without fully qualifying the drive:\\path\\to\\executable?
I thought I was on to a solution by scanning HKLM\Software\Clients recursively for shell\open\command, then adding each referenced location temporarily to %PATH%:
rem // temp add installed clients to %PATH% to make "call :display" behave like "start"
setlocal enabledelayedexpansion
for %%a in (HKLM HKCU) do for /f "tokens=2*" %%I in (
'REG QUERY %%a\Software\Clients /s /f command /k /ve ^| find "(Default)"'
) do if "%%~I"=="REG_EXPAND_SZ" (
if /i "%%~xJ"==".exe" (
if "!PATH:%%~J\..=!"=="!PATH!" path !PATH!;%%~J\..
) else for %%# in (%%J) do if /i "%%~x#"==".exe" (
if "!PATH:%%~#\..=!"=="!PATH!" path !PATH!;%%~#\..
)
) else (
if /i "%%~xJ"==".exe" (
if "!PATH:%%~dpJ=!"=="!PATH!" path !PATH!;%%~dpJ
) else (
for %%# in (%%J) do if /i "%%~x#"==".exe" (
if "!PATH:%%~dp#=!"=="!PATH!" path !PATH!;%%~dp#
)
)
)
endlocal & path %PATH%
That works reasonably well, but it still falls short of what start can access. For example:
start "" wordpad
works, whereas
wmic process call create "wordpad.exe"
fails.
I remember a discussion about this very topic either on DosTips.com or here on SO but I cannot find it. Hopefully somebody does so we can mark this question as a duplicate.
We know that the batch files will search the current directory and then the path variable to find an executable. The START command also searches the following Registry path
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
So you have a few options to find the executable.
You can use the WHERE command which searches the current directory and the directories in the PATH variable.
where notepad.exe
You can also just search the path variable with a FOR command.
for %%I in (notepad.exe) do echo %%~$PATH:I
And of course you can search the registry path as I mentioned above by doing a REG QUERY.
Edit2
This may be of interest regards to what you are doing (as opposed to why something works the way it does).
From a previous answer
Can I create shorthand names for use inside cmd?
See Doskey /?.
You could do this doskey cddesk=cd "%userprofile%\desktop"
Then type cddesk.
By putting all your macros in a batch file you can autoload. Of course
you could do this with batchfiles too.
From Technical Reference to the Windows 2000 Registry, Microsoft,
2000.
AutoRun HKCU\Software\Microsoft\Command Processor
Data type Range Default value
REG_SZ list of commands There is no default value for this entry.
Description
Contains commands which are executed each time you start Cmd.exe.
Also see this batchfile https://pastebin.com/A2qLw8r3 that list
special names.
In a command prompt start shell:desktop
Or in Start - Run (Winkey + R) just shell:desktop
Edit
I'll just add some caveats here.
This is about opening executables using Start command. A massive amount of rules apply to non executable files.
Not using Start CMD pre-processes the command line and sends a FQFN to CreateProcess - so it's CMD that searches the path not CreateProcess.
https://learn.microsoft.com/en-us/windows/desktop/shell/launch is the documentation for ShellExecute. Everything ends up calling CreateProcess https://learn.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw. Plus CMD preprocessing is detailed here https://books.google.com.au/books/about/Windows_NT_Shell_Scripting.html?id=jrdQAAAAMAAJ&redir_esc=y. Also start /? provides documentation for all three ways to start files. A summary is here Command to run a .bat file
Some fun facts. CMD if it can't recognise a file extension will attempt to execute it. ShellExecute will content sniff unknown files https://learn.microsoft.com/en-us/windows/desktop/com/filetype-key.
quote from rojo: Thanks for the link dump. I'm struggling to understand how ShellExecute can save me from having to fully qualify path names though. That was my primary question. "To use ShellExecute or ShellExecuteEx, your application must specify the file or folder object that is to be acted on, and a verb that specifies the operation." It's the "specify the file or folder object" part that I'm asking about.
It uses the 6 steps under CreateProcess and if that turns up nothing it uses App Paths. If a verb is not specified the default verb is used (usually Open). See my answer here How do i automate the simulation of right clicking a file and selecting the first option using vbscript.
So it an intersection of 4 technologies. Compatibility with MSDos, changes made by IBM for OS/2 and updated by Microsoft for Windows 2000, the standard windows way of starting programs CreateProcess, and with Windows 95 we got shell functions which are based on OLE
quote from rojo: Snap! You're right! In PowerShell I was able to create a System.Diagnostics.Process object, set $ps.StartInfo.UseShellExecute = $true, and then start "wordpad" without any file extension or fully qualified path. Setting the .UseShellExecute property to $false caused the execution to fail. How interesting!

Batch Script: Move Folder & Contents to New Path

Problem
I'm trying to move a folder (ex. \\myUNC\folder1) and its contents to another folder (ex. \\myUNC\Parent\folder1). There are two easy enough ways I'd typically do this - either using move (similar to here) or using ren (similar to here).
Example Code
set oldPath=\\myUNC\folder1
set newPath=\\myUNC\Parent\folder1
move "%oldPath%" "%newPath%"
::ren"%oldPath%" "%newPath%"
Troubleshooting
When attempting the move solution in my first like, I get the error:
The filename or extension is too long. 0 dir(s) moved.
As a result, I tried ren like in my second link, which gave the error:
The syntax of the command is incorrect.
For this second error, I'm assuming that is because I'm passing the path as part of my variable - which ren doesn't accept. The batch calling this change is NOT in the same directory as the folder or its new path. As a result I can't use current directory code (like ren or cd), at least as far as I know.
If anyone has a possible solution it would be greatly appreciated! Thanks.
The filename or extension is too long. 0 dir(s) moved.
This error refers to a 'feature' in Windows that limits file names to a maximum of 255 characters. To overcome this, you would need to shorten the names of the folders on the Network drive. See Maximum filename length in NTFS (Windows XP and Windows Vista)?
The syntax of the command is incorrect.
This error occured because you cannot state a new folder for the ren command. A file can only be renamed in the same folder, not even subdirectories are allowed. But the reason why you got The syntax of the command is incorrect. error, is because you left out a space in between the ren and the "
Possible solution:
Depending on your scenario, you might be able to pushd into the folder and then use the move command. In my experience, some commands don't respond equally to UNC locations vs local file locations (ex. if exist "\\UNC\"):
#echo off
pushd \\myUNC\
set oldPath=folder1
set newPath=Parent\folder1
move "%oldPath%" "%newPath%"
popd
This will only work though, if you haven't exceeded the 255 char limit
After a lot of troubleshooting, I was able to find a solution with no errors!
Solution
set oldPath=\\myUNC\folder1
set newPath=\\myUNC\Parent\folder1
robocopy /move "%oldPath%" "%newPath%"
Why
Robocopy is a newer command from Microsoft, and accounts for filename strings longer than 256 characters (apparently the issue with move and/or copy command).
You can google robocopy to learn more about the command options and parameters, but its fairly straight forward. For my issue, I wanted to move the file, so I just used the /move option, which deletes the original folder and files.

Read current drive of batch file and use drive name in command

I have the following problem: We send customers a USB-stick with content that they need to import onto a Linux-computer via a import-function (no influence on the Linux-part, only on the USB-stick part). The Linux import-function cannot read files with spaces, i.e. the file "system volume information" which is created on every drive of a Windows computer disrupts the import function.
With a google research I found out, how I can delete this file on the drive of the USB-Stick. If I do that before disconnecting the USB-stick from my Windows computer, I can import the content on the Linux computer. I do this with a batch-file containing the following command:
rd /s /q D:\"system volume information"
However, those USB-Sticks are sent out to customers that will want to view the content on a Windows-computer as well, before importing it, i.e. the file "system volume information" is created anew. I would like to make it as simple as possible for the customer and put a batch-file on the stick where they simply have to double-click on it in order to delete the file. This is where my problem lies: I cannot be sure, that it will be drive D: where the stick will lie. This is why I am looking for a function or command that reads the drive of the batch-file (USB-Stick) and does the command of delete "system volume information". I read some things about %~d0 but I could not find out how I specifically have to write the command to make it work.
Would you be able to help me? I have very limited experience with batches, so I apologize if this question seems very easy for you.
Thanks
Milak
I have not tested the code:
#echo off
set P=%~d0
set "P=%P%\system volume information"
rd /s /q "%P%"

User CMD Batch Interaction

I am creating a batch file that will install files into a certain location on a computer. this could be used for various things such as game mods, folder backups, etc. If i am trying to have the user type in the path they want the file to be sent to. How would I do that? I would like to have that path pasted into a .txt file, that way i can access it later in the program. I have tried the ">" and it works on putting the path into the file. How do I extract that information. "Direct Question" How can I take user input, and use it to paste files somewhere else in the computer using the user's path that was specified.
How many questions do you want for your money?
To input a string:
set /p "installdir=Install in which directory? "
At any point thereafter, you can use %installdir% to access the directoryname input.
If you need to save the directoryname in a file, then use
>"c:\wherever\you\want\filename.txt" echo %directoryname%
and to read it,
for /f "usebackqdelims=" %%a IN ("c:\wherever\you\want\filename.txt") do set "dirread=%%a"
or
set /p "dirread="<"c:\wherever\you\want\filename.txt"
and "pasting" or probably copying,
copy /b "x:\directory from\filename.whatever" "%dirread%\"
to copy the file "filename.whatever" from directory "x:\directory from\" to directory in the environment variable dirread as read by one of the previous two methods or substitute directoryname for dirread to use the directory name originally entered.

Isolate Server Name From UNC with FOR in Batch

The goal of my overall script is to - from a central server - check individual site servers for files. If files exist, go do some work. This smaller exerpt is to aid creation of multiple entries for site names, logs, dates, and times of which I want to check the UNC path and use a variable for the site server name - the first 'token' of the UNC path. I used the example guide from Rob van der Woude's scripting page (these loops are new to me and it appears to be a basic resource) to create the FOR loop exampled below.
#echo off
SET PATH=\\UNCMainPath\SubPath1\SubPath2
FOR /F "tokens=1 delims=\" %%A IN (%PATH%) DO SET FOLDER=%%A
ECHO %FOLDER%
This is short and clean and will be easy to repeat for ~50 site servers. This code, however, does not work. The error I receive is:
The system cannot find the file \\UNCMainPath\SubPath1\SubPath2.
ECHO is off.
This, of course, tells me something is wrong before the FOR loop begins, but for the life of me I can't figure what is incorrect. Even with trash example text, I've been able to SET a variable and have it ECHO back as whatever it was set for. What have I done wrong?
Thank you to #Endoro.
Using ("%PATH%") did the trick. I forgot to enclose the variable with quotes.

Resources