Jump to content











Photo
- - - - -

Please help me to go ahead ?

cmd winpe boot.wim usb booting multibooting

  • Please log in to reply
146 replies to this topic

#76 cdob

cdob

    Gold Member

  • Expert
  • 1343 posts

Posted 28 July 2017 - 09:06 PM

Should I use any other copy tool instead of 'robocopy' in Win10PESE ? Which is best and native copy tool which I use in Win10PESE project ?

Robocopy is the first choice to copy files still.
And at a default configuration, permissions are set to system / admin full access. Robocopy will work from a PE.
However a end user may have changed the default permission.

Which kind of machines do you like to support?
Knwon ones with default environment?
Unknown machines with strange end user changes?

Out of the box there is dism /capture-image.
Yes, not a copy tool. But the purpose is to create a image.
You may use this to create a backup. 7-zip can read the wim file.
Dism can read files, in cases robocopy has no access.

At a default configuration: use robocopy
At a strange configuration: try dism

#77 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 28 July 2017 - 11:29 PM

C:\Data>SET MostFreePart
MostFreePart=D:
MostFreePartMB=4893

C:\Data>IF DEFINED Removable (
FOR %A IN ((null)) DO CALL :Sort_Rval %A !VOL_%A!
 FOR /F "tokens=2 Delims==" %A IN ('SET RFree_') DO SET MostFreeRem=%A
 SET MostFreeRemMB=!VOL_!
 SET MostFreeRemMB=0
 SET MostFreeRemMB=
 SET MostFreeRem
)

C:\Data>IF NOT DEFINED MostFreePartMB SET /A MostFreePartMB=0

C:\Data>IF NOT DEFINED MostFreeRemMB SET /A MostFreeRemMB=0

C:\Data>IF 4893 GEQ 18061 (SET FREEDRIVE=D: )  ELSE (IF 0 GEQ 18061 (SET FREEDRIVE= ) )

C:\Data>IF DEFINED FREEDRIVE (GOTO :DO_BACKUP )  ELSE (Explorer , )

C:\Data>ECHO BACKUP DRIVE is D:
BACKUP DRIVE is D:

It looks OK...

IF 4889 GEQ 1269 (SET FREEDRIVE=D: )  ELSE (IF 0 GEQ 1269 (SET FREEDRIVE= ) )

But following line looking ODD ? I could not understood execution of following commands ??

IF 4893 GEQ 18061 (SET FREEDRIVE=D: )  ELSE (IF 0 GEQ 18061 (SET FREEDRIVE= ) )

Both conditions are FALSE, then why FREEDRIVE=D: ??



#78 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 29 July 2017 - 08:40 AM

It is most probably a leftover, when checking any condition you may want to either undefine (or set to 0/space) the variable involved and/or check value immediately before and after check.
 
 
SET FREEDRIVE=
SET FREEDRIVE
IF 4893 GEQ 18061 (SET FREEDRIVE=D: ) ELSE (IF 0 GEQ 18061 (SET FREEDRIVE= ))
SET FREEDRIVE
AND check that values compared in a numerical comparison are actually numbers, maybe one or both are strings?  :dubbio:

I.e.
C:\batches>IF 2 GEQ 10 (ECHO GEQ) ELSE (ECHO LSS)
LSS

C:\batches>IF "2" GEQ "10" (ECHO GEQ) ELSE (ECHO LSS)
GEQ
:duff:
Wonko

#79 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 29 July 2017 - 12:29 PM

Test-

IF %MostFreePartMB% GEQ %BACKUP_SIZE% (ECHO GEQ) ELSE (ECHO LSS)
IF "%MostFreePartMB%" GEQ "%BACKUP_SIZE%" (ECHO GEQ) ELSE (ECHO LSS)

Output-

C:\Data>IF 4889 GEQ 18061 (ECHO GEQ )  ELSE (ECHO LSS )
LSS

C:\Data>IF "4889" GEQ "18061" (ECHO GEQ )  ELSE (ECHO LSS )
GEQ

So which one is STRING ? Is MostFreePartMB string ?



#80 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 29 July 2017 - 01:40 PM

I really don't know how to talk with you and understand each other. :unsure:

Make TWO tests.
FIRST TEST:

SET FREEDRIVE=
SET FREEDRIVE
IF %MostFreePartMB% GEQ %BACKUP_SIZE% (SET FREEDRIVE=D: ) ELSE (IF %MostFreeRemMB% GEQ %BACKUP_SIZE% (SET FREEDRIVE=E: ))
SET FREEDRIVE
What is the output?

(drives D: or E: are ONLY for the example)

:duff:
Wonko

#81 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 29 July 2017 - 02:10 PM

TEST-1

IF %MostFreePartMB% GEQ %BACKUP_SIZE% (ECHO GEQ) ELSE (ECHO LSS)
IF "%MostFreePartMB%" GEQ "%BACKUP_SIZE%" (ECHO GEQ) ELSE (ECHO LSS)

SET FREEDRIVE
IF %MostFreePartMB% GEQ %BACKUP_SIZE% (
SET FREEDRIVE=%MostFreePart%
) ELSE (
IF %MostFreeRemMB% GEQ %BACKUP_SIZE%  (
SET FREEDRIVE=%MostFreeRem%
)
)
SET FREEDRIVE

Output-1

C:\Data>IF 4888 GEQ 18061 (ECHO GEQ )  ELSE (ECHO LSS )
LSS

C:\Data>IF "4888" GEQ "18061" (ECHO GEQ )  ELSE (ECHO LSS )
GEQ

C:\Data>SET FREEDRIVE
FREEDRIVE=D:

C:\Data>IF 4888 GEQ 18061 (SET FREEDRIVE=D: )  ELSE (IF 0 GEQ 18061 (SET FREEDRIVE= ) )

C:\Data>SET FREEDRIVE
FREEDRIVE=D:

TEST-2

IF %MostFreePartMB% GEQ %BACKUP_SIZE% (ECHO GEQ) ELSE (ECHO LSS)
IF "%MostFreePartMB%" GEQ "%BACKUP_SIZE%" (ECHO GEQ) ELSE (ECHO LSS)

SET FREEDRIVE=
SET FREEDRIVE
IF %MostFreePartMB% GEQ %BACKUP_SIZE% (
SET FREEDRIVE=%MostFreePart%
) ELSE (
IF %MostFreeRemMB% GEQ %BACKUP_SIZE%  (
SET FREEDRIVE=%MostFreeRem%
)
)
SET FREEDRIVE

OUTPUT-2

C:\Data>IF 4888 GEQ 18061 (ECHO GEQ )  ELSE (ECHO LSS )
LSS

C:\Data>IF "4888" GEQ "18061" (ECHO GEQ )  ELSE (ECHO LSS )
GEQ

C:\Data>SET FREEDRIVE=

C:\Data>SET FREEDRIVE
Environment variable FREEDRIVE not defined

C:\Data>IF 4888 GEQ 18061 (SET FREEDRIVE=D: )  ELSE (IF 0 GEQ 18061 (SET FREEDRIVE= ) )

C:\Data>SET FREEDRIVE
Environment variable FREEDRIVE not defined

I have not used SET FREEDRIVE= in TEST-1 and it gives ODD outputs. When I have added SET FREEDRIVE in TEST-2, then it gives OUTPUT as expected. Sorry 'Wonko'...I just forget to use SET FREEDRIVEin script of Post #60. It's why I have to face ODD behavior of variables...In Test 1, previous value of FREEDRIVE (user Anand) remains and automatically shown in second loop of user 'Kdevd'. So I have to reset FREEDRIVE value for each USER cycle...

 

Is it also necessary to define following variables in Post #60 ?

 

MostFreePart=

MostFreePartMB=

MostFreeRem=

MostFreeRemMB=

 

Should I define these variables either at the starting of the script or at the starting of subroutine :FREEDRIVE ? Does it matter ?



#82 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 30 July 2017 - 11:04 AM

@devadevadev
The general idea is to ALWAYS be able to know which possible values (or non-values, such as "undefined") a variable has and be prepared to have each test ready for these values.

I am not so sure that is a good idea to go in several iterations of users.
I mean there could well be "edge" cases in which each user profile is backed up to a different drive, sometimes and internal one, sometimes an external one.

Probably it would make more sense to first find the two most free drives (internal and external) then calculate the amount of space needed by the sum of ALL users profiles and only then run the backup so that all users go to the same drive.

@zharif
Sure, the parsing of the "title" line was (mainly) an exercise in futility.
The idea (probably flawed) was to use the titles of columns to detect language (and thus recognize "Partition" and "Removable").
If the "issue" is the double Diskpart call, we can do with just one:
 

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET /A Field=0
SET /A ProgrOffset=0
SET /A LineN=0
ECHO ---------1---------2---------3---------4---------5---------6---------7---------8
ECHO 12345678901234567890123456789012345678901234567890123456789012345678901234567890
FOR /F "skip=7 tokens=* delims=" %%A IN ('ECHO LIST VOLUME^|DISKPART') DO (
SET Line=%%A
SET /A LineN+=1
CALL SET Line_!LineN!=!Line!
IF "---"=="!Line:~2,3!" GOTO :OutOfFor
)
:OutOfFor
ECHO %Line_1%
ECHO %Line_2%
CALL :parse_hyphens %Line_2%
GOTO :EOF

:parse_hyphens
SET /A Field+=1

SET /A ProgrOffset+=2

SET Field_%Field%=%1

FOR /L %%B IN (12,-1,1) DO (
SET string=!Field_%Field%:~0,%%B!
IF !String!==!Field_%Field%! SET /A Length_%Field%=%%B
)


SET /A Offset_%Field%=%ProgrOffset%
SET /A ProgrOffset=%ProgrOffset%+!Length_%Field%!

SET /A Title_Offset=!Offset_%Field%!-1
SET /A Title_Length=!Length_%Field%!+2
SET Field_%Field%=§!Line_1:~%Title_Offset%,%Title_Length%!§

::Trim excess spaces
SET Field_%Field%=!Field_%Field%:    §=§!
SET Field_%Field%=!Field_%Field%:   §=§!
SET Field_%Field%=!Field_%Field%:  §=§!
SET Field_%Field%=!Field_%Field%: §=§!
SET Field_%Field%=!Field_%Field%:§ =!
SET Field_%Field%=!Field_%Field%:§=!

SET Field_%Field%
SET Offset_%Field%
SET Length_%Field%
ECHO.
IF NOT "%2"=="" SHIFT&&GOTO :parse_hyphens

GOTO :EOF

Though using the "skip" in a for loop is always a "risk" as different languages/versions of diskpoart may output one more (or less) line before the "hyphens" one.

To get just the field lengths (anonymous) this is of course enough:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET /A Field=0
SET /A ProgrOffset=0
ECHO ---------1---------2---------3---------4---------5---------6---------7---------8
ECHO 12345678901234567890123456789012345678901234567890123456789012345678901234567890
FOR /F "tokens=* delims=" %%A IN ('ECHO LIST VOLUME^|DISKPART^|FIND "---------"') DO ECHO %%A&&CALL :parse_hyphens %%A
GOTO :EOF

:parse_hyphens
SET /A Field+=1
SET /A ProgrOffset+=2

SET Field_%Field%=%1

FOR /L %%B IN (12,-1,1) DO (
SET string=!Field_%Field%:~0,%%B!
IF !String!==!Field_%Field%! SET /A Length_%Field%=%%B
)


SET /A Offset_%Field%=%ProgrOffset%
SET /A ProgrOffset=%ProgrOffset%+!Length_%Field%!

SET Field_%Field%
SET Offset_%Field%
SET Length_%Field%
ECHO.
IF NOT "%2"=="" SHIFT&&GOTO :parse_hyphens

GOTO :EOF

:duff:

Wonko



#83 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 30 July 2017 - 12:59 PM

I am not so sure that is a good idea to go in several iterations of users.
I mean there could well be "edge" cases in which each user profile is backed up to a different drive, sometimes and internal one, sometimes an external one.

Probably it would make more sense to first find the two most free drives (internal and external) then calculate the amount of space needed by the sum of ALL users profiles and only then run the backup so that all users go to the same drive.

 

i was also thinking to do exactly the same thing. I think it is going to be a bit Tricky and Difficult ?? But how I will manage :DO_BACKUP section to backup  each user folder content to different folders *(with user name) in Backup Drive ? Will I not have to execute USER cycle twice ? One during calculation of TOTAL_SIZE and one during :DO_BACKUP ?

 

Will we set a variable ALLUSERS having all usernames ?

ALLUSERS: Anand  Kdevd  Wonko  Steve....etc ?

How we will add different sizes of each user directories ? 



#84 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 30 July 2017 - 02:53 PM



SET USER=%%A& SET USERDIR=%SYSPART%\Users\%%A


SET USER=%%A& SET USERDIR=%SYSPART%\Users\%%A
SET ALLUSERS=!ALLUSERS!§!USER!

(to make an arbitrary character delimited list, as spaces as delimiters may be an issue :unsure:)

 

More generally you need to re-engineer the script:

1) List all users

2) calculate the space needed for each user profile backup AND add it to a progressive sum

3) find the suitable free drive capable of containing the sum of all users profiles space 

4) run the backup for the list of users in #1

 

:duff:

Wonko



#85 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 31 July 2017 - 02:34 AM

ALL_USERS=ºAnandºKdeva
ALL_USERSDIR=ºC:\Users\AnandºC:\Users\Kdeva
:DO_BACKUP
ECHO BACKUP DRIVE is %FREEDRIVE%
FOR /F "tokens=2 Delims=§=" %%A IN ('%ALL_USERS%' '%ALL_USERSDIR%') DO (
mkdir "%FREEDRIVE%\BACKUP_%ALL_USERS%_%DATETIME%" & Explorer.exe "%FREEDRIVE%\BACKUP_%ALL_USERS%_%DATETIME%"
robocopy "%ALL_USERDIR%\Music" "%FREEDRIVE%\BACKUP_%ALL_USERS%_%DATETIME%\Music" /E /MT:1
)
GOTO :EOF

I know I am using something wrong and invalid syntax. Can you please correct that ? Am I using correct LOGIC ?

IF DEFINED Removable (
FOR %%A IN (%Removable%) DO CALL :Sort_Rval %%A !VOL_%%A!
FOR /F "tokens=2 Delims==" %%A IN ('SET RFree_') DO SET MostFreeRem=%%A
SET MostFreeRemMB=!VOL_%MostFreeRem%!
SET MostFreeRemMB=%MostFreeRemMB: =%
SET MostFreeRemMB=%MostFreeRemMB:~0,-6%
SET MostFreeRem
)
IF NOT DEFINED MostFreeRemMB SET /A MostFreeRemMB=0

Above code skip if there is no Removable USB Drive connected. But why It is not executing is Removable USB Drive is connected ? Is it also a invalid syntax ?



#86 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 31 July 2017 - 08:15 AM

Well, but before or later you will need to learn the FOR syntax yourself.

http://www.robvander...e.com/ntfor.php

 

It is not that you are using "something wrong syntax", you are using a completely random one.

The logic is flawed because of syntax and viceversa.

 

If you go through the above given link you may notice that you cannot have more than one "set" for the "IN" of a FOR command, 

And as always you are trying to make too many things all together, which is fine once you have made sure that the single step is working as expected, but beginning with a too complex layout is and will be unlikely to work and more difficult to troubleshoot.

 

Start simple, what you want is to have one by one the User names (and you CANNOT use two "sets" inside a FOR):

FOR /F "tokens=2 Delims=§=" %%A IN (' SET %ALL_USERS%') DO (ECHO %%A)

OR

FOR /F "tokens=2 Delims=§" %%A IN ("%ALL_USERS%") DO (ECHO %%A)

 

These correspond to two of the types of FOR /F command listed in the given page:

FOR    /F ["options"] %variable IN ('command') DO command [command-parameters]

FOR    /F ["options"] %variable IN ("string") DO command [command-parameters]

 

In the first the "set" is the output of a command (between single quotes) in the second it is a string (between double quotes).

 

The idea of this thread is not that we write that batch for you, but rather that if and when you find an obstacle, we try and suggest you a way to get past it, but at least you have to try, not that you write random things, (that won't work), state genericlaly that they don't work and then ask how to write them so that they work.,

 

You write something, you explain WHY you wrote it that way, you describe WHAT result you would have expected, you write WHAT OTHER result you get instead and then we will try and help you.

 

:duff:

Wonko



#87 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 31 July 2017 - 08:26 AM

@zharif

Only to continue in the exercise, a simpler way:



@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET /A Counter=0
FOR /F "tokens=* delims=" %%A IN ('ECHO LIST VOLUME^|DISKPART^|FIND "---------"') DO SET Line=%%AE
SET Line=%Line:  =EB%
FOR /L %%B IN (1,1,79) DO CALL :!Line:~%%B,1! %%B
GOTO :EOF

:E
SET /A Field_%Counter%_L=%1-!Field_%Counter%_B!
SET Field_!Counter!
GOTO :EOF

:B
SET /A Counter+=1
SET /A Field_%Counter%_B=%1+1
:-
GOTO :EOF

:duff:

Wonko



#88 Zharif

Zharif

    Frequent Member

  • .script developer
  • 153 posts
  • Location:Germany
  •  
    Germany

Posted 31 July 2017 - 01:33 PM

As for me, I verify that your "little gray cells are in almost perfect efficiency"  - this is another touch of genious.

Your handling of strings/string substitutions is really exceptional.

Thanks for this lesson (by the way, it's so awesome simple).

If I may, write some comments into this code to help others (not familar in batching language) to understand it.

 

So far, you made everything available to any user (especially to devdevadev) to do anything what he/she wants with this diskpart output.

Now, appending a code (e.g. mine) to get filtered drive letter outputs should be just a question of coding preferences.

 

(still wondering ...from where does he gets his starting ideas?)

 

Zharif



#89 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 31 July 2017 - 02:21 PM

 (by the way, it's so awesome simple).

If I may, write some comments into this code to help others (not familar in batching language) to understand it.

Well IMHO (and as Leonardo Da Vinci taught us) simplicity is the ultimate sophistication. :)

 

Adding comments may prove more difficult than to actually write the small batch,  usually a good way to explain how a batch behaves is to use ECHO ON/OFF statements and PAUSEs, but in this case the use of DELAYEDEXPANSION "bangs" (!) makes the output anyway difficult to read. :unsure:

 

:duff:

Wonko



#90 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 01 August 2017 - 02:13 AM

OK..Sir, reading is continue with my low IQ...BTW

 

syspart-

 

for MBR disk scheme there is only 1 active primary partition.
for EFI there is only 1 partition which have the PARTITION_SYSTEM_GUID guid.
 
How I can assigns 'syspart' the Z:\ as a dosdevice using batch, so disk management or unelevated explorer will not show it. How Can I open Elevated File Explorer using batch script ?
 
Really don't know about this dosdevice (some good pages please ?) . Is is possible to deal with dosdevice using cmd ?


#91 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 01 August 2017 - 10:09 AM

 

OK..Sir, reading is continue with my low IQ...BTW

 

syspart-

 

for MBR disk scheme there is only 1 active primary partition.
for EFI there is only 1 partition which have the PARTITION_SYSTEM_GUID guid.
 
How I can assigns 'syspart' the Z:\ as a dosdevice using batch, so disk management or unelevated explorer will not show it. How Can I open Elevated File Explorer using batch script ?
 
Really don't know about this dosdevice (some good pages please ?) . Is is possible to deal with dosdevice using cmd ?

 

Maybe you should ask to the nice guy (JFX :)) that indirectly suggested it:
http://www.msfn.org/...comment-1142307

 

JFYI, it is not like failing to provide references and context actually helps in answering you, it is only by sheer luck that I noticed your post on MSFN and thus get some background.

 

Not that I actually fully understand what JFX meant, but in the context of his WinntSetup program it probably generically describes what that program does, not what you want/need to do. :unsure:

 

Dosdevice is - generally speaking - the name for a set of Registry keys that reside in HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices 

There is one \DosDevice\ key for each drive letter assigned and usually a corresponding \Volume{<GUID>} entry.

 

Usually MOUNTVOL is used to manage these, but I have no idea how/why a drive letter can be assigned AND not be seen in "disk management or unelevated explorer" :dubbio:.

 

 

:duff:

Wonko



#92 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 01 August 2017 - 04:33 PM

ALL_USERS=ºAnandºKdeva
ALL_USERSDIR=ºC:\Users\AnandºC:\Users\Kdeva

FOR /F "tokens=2 Delims=§=" %%A IN (' SET %ALL_USERS%') DO (ECHO %%A)

OR

FOR /F "tokens=2 Delims=§" %%A IN ("%ALL_USERS%") DO (ECHO %%A)

May be second code should be

FOR /F "tokens=1 Delims=§" %%A IN ("%ALL_USERS%") DO (ECHO %%A)

It echo only 'Anand' ? why no also echo second username i.e 'Kdevd'

First code is looking invalid ? Should it be ?

@echo off
pushd "%~dp0"
setlocal EnableDelayedExpansion

SET USER=
SET USERDIR=
SET ALL_USERS=
SET ALL_USERSDIR=
FOR /F %%A IN ('DIR "C:\Users\" /B 2^>nul') DO (
if /i not "%%A"=="Public" FOR /F %%B IN ('DIR "C:\Users\%%A\" /B 2^>nul ^|FIND /I "Desktop" ') DO (
IF EXIST "C:\Users\%%A\Desktop" (
SET USER=%%A& SET USERDIR=C:\Users\%%A
ECHO USER is !USER! and USER DIRECTORY is !USERDIR!
SET ALL_USERS=!ALL_USERS!§!USER!
SET ALL_USERSDIR=!ALL_USERSDIR!§!USERDIR!
)
)
)
SET ALL_USERS
FOR /F "tokens=2 Delims=§=" %%A IN ('SET ALL_USERS') DO (ECHO %%A)
PAUSE

which gives following result 

Anand
C:\Users\Anand

I have two user account 'Anand' and 'Kdevd'. Why above FOR loop does not ECHO 'Kdevd' and 'C:\Users\Anand' too ? I think it should echo all user name ? Why it echo only first one ? Should not FOR loop execute (TWICE) for each value of ALL_USERS ?

ECHO %%A)
Anand
C:\Users\Anand

Now how i can assign values of %%A to following variables ?

USER=Anand
USERDIR=C:\Users\Anand


#93 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 01 August 2017 - 06:25 PM

Naah, you have a list made of two tokens:

1) Anand

2) Kdevd

And you expressly asked to have only first one by giving a value to tokens AND using just first variable.

But anyway you cannot expect (normally) to know if there is one, two, three (or 42) users.

 

You could use a simple FOR, but you would need double quotes as an user name or path can well have a space in the name.

Check:



@echo off
setlocal EnableDelayedExpansion
SET USER=
SET USERDIR=
SET ALL_USERS=
SET ALL_USERSDIR=
SET Counter=0
FOR %%A IN ("Anand" "Kdev" "Someone else") DO (
ECHO %%A
SET USER=%%~A
SET USERDIR=C:\Users\%%~A
ECHO USER is !USER! and USER DIRECTORY is !USERDIR!
SET ALL_USERS=!ALL_USERS!§!USER!
SET ALL_USERSDIR=!ALL_USERSDIR!§!USERDIR!
)
SET ALL_USERS
ECHO.

FOR /F "tokens=1,2,3 delims=§" %%A IN ("%ALL_USERS%") DO (
ECHO %%A
ECHO %%B
ECHO %%C
)
ECHO.

SET PARSABLE_USERS=%ALL_USERS: =__%
SET PARSABLE_USERS=%PARSABLE_USERS:§= %
CALL :Parse_Users %PARSABLE_USERS%
ECHO.

GOTO :EOF

:Parse_Users
SET /A Counter+=1
SET User_%Counter%=%1
SET User_%Counter%=!User_%Counter%:__= !
SET User_%Counter%

IF NOT "%2"=="" SHIFT&GOTO :Parse_Users
GOTO :EOF

:duff:

Wonko



#94 Zharif

Zharif

    Frequent Member

  • .script developer
  • 153 posts
  • Location:Germany
  •  
    Germany

Posted 01 August 2017 - 10:30 PM

Hmm, I think it should work without dblquoting the UserNames prior which is shorter but not as foolproofing as Wonkos code.

Please read my comments.

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

:: Set Volume drive letter and UserDir you want to access from PE
SET "TargetVol=C:"
SET "TargetUserDir=%TargetVol%\Users"

:: Use the DIR command get directories only [/A:D switch].
:: The -H switch excludes hidden files/directories such as
:: Default, AllUsers, andDefault User [if present].
:: If directory Public is present [usually not hidden] you're in need to
:: add an exclusion via FIND /V command.
:: - feel free to change the dir switches or the example FIND exclusion list.
:: I use a semicolon as delimiter for each directory found
:: [such as the Path environmental variable].

:: loop sets each user in ascending order, all users as a semicolon delimited list,
:: and all users dir as a semicolon delimited list [such as the Path variable].
FOR /F %%a IN ('DIR /B /A:D-H "%TargetUserDir%"^|FIND /V "Public"') DO (
  SET /A C+=1
  SET "_User_!C!=%%a"
  SET "_All_Users=!_ALL_USERS!;%%a"
  SET "_All_UsersDir=!_ALL_USERSDIR!;%TARGETUSERDIR%\%%a"
)
:: remove everything before the first semicolon
:: [semicolon included] from variable values
SET "_All_Users=%_ALL_USERS:*;=%"
SET "_All_UsersDir=%_ALL_USERSDIR:*;=%"
set _
ECHO.
ECHO Just for testing purposes we no add a new user name
ECHO [Someone Else] that contains spaces:
ECHO.
SET _All_UsersDir=%_ALL_USERSDIR%;%TARGETUSERDIR%\Someone Else
SET _

:: This loop replaces any semicolon in the All_UsersDir listing with
:: a dblquote+space+dblquote. UserNames are now surrounded by dblquotes.
:: In this way you're able to display any UserName[although it contains spaces]
:: orrectly in a for loop.
:: You also may have a look at: https://ss64.com/nt/path.html
ECHO.
FOR %%a IN ("%_ALL_USERSDIR:;=" "%") DO (
  echo %%a
)
CMD /K&EXIT


  • devdevadev likes this

#95 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 02 August 2017 - 04:18 AM

I can echo either USERS or USERDIR at a time either with FOR method or 'Wonko' method. As you know I want to echo both USERS and USERSDIR within :DO_BACKUP section.

SET USERS=%ALL_USERS: =__%
SET USERS=%USERS:;= %
SET USERSDIR=%ALL_USERSDIR: =__%
SET USERSDIR=%USERSDIR:;= %
CALL :DO_BACKUP %USERSDIR%
GOTO :EOF

:DO_BACKUP
SET USERS=%1
SET USERS=!USERS:__= !
SET USERSDIR=%1
SET USERSDIR=!USERSDIR:__= !
ECHO %USERS% 
ECHO %USERDIR%
PAUSE
IF NOT "%2"=="" SHIFT&GOTO :DO_BACKUP
GOTO :EOF

Is it possible to call a subroutine with two variables ? Something like this ? so that I can echo both USERS and USERSDIR ?

CALL :DO_BACKUP %USERS% %USERSDIR%

Can you please explain working of following command ? I don't get it correctly..

SET USERS=%1
SET USERSDIR=%1


#96 Zharif

Zharif

    Frequent Member

  • .script developer
  • 153 posts
  • Location:Germany
  •  
    Germany

Posted 02 August 2017 - 05:51 AM

EDIT:

I hope getting your point.

If it's only to take care about paths and user names with spaces the following command should work fine.

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

SET "TargetVol=C:"
SET "TargetUserDir=%TargetVol%\Users"

FOR /F "tokens=*" %%a IN ('DIR /B /A:D-H "%TargetUserDir%"^|FIND /V "Public"') DO (
  SET "_User_%%a=%TARGETUSERDIR%\%%a"
  SET "_All_Users=!_ALL_USERS!;%%a"
  SET "_All_UsersDir=!_ALL_USERSDIR!;%TARGETUSERDIR%\%%a"
)

FOR /F "tokens=2* delims=_=" %%a IN ('SET _User_') DO (
  ECHO User: %%a
  ECHO Path: %%b
  ECHO.
)

cmd /k


  • devdevadev likes this

#97 Zharif

Zharif

    Frequent Member

  • .script developer
  • 153 posts
  • Location:Germany
  •  
    Germany

Posted 02 August 2017 - 07:57 AM

This is much better...

FOR /F "delims tokens=*" %%a IN ...

Changed in my previous post.



#98 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 13750 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 02 August 2017 - 09:00 AM

@Zharif

JFYI:

https://xkcd.com/327/

 

Crazy at it may seem, semicolon is a valid character inside a path or filename.

It will never happen (just like it will never happen that a path or filename contains § or two contiguous underscores __, still it is similarly not entirely "kosher".

 

At the end of the day, and with some attention, the only character that can surely be used as separator between strings representing filenames, paths and usernames and that is easily available on the keyboard is TAB (which on one hand makes the batch more readable, and on the other, being invisible needs particular attention when copying/pasting). 

The good news are that it is a separator in CALLs (i.e. it separates  arguments just like space).

The problem with spaces remains, however.

Something like this:
SET PARSABLE_USERS=%ALL_USERS: =[SPACE]%

...

SET User_%Counter%=!User_%Counter%:[SPACE]= !

may do, but most probably the canonical way of using double quotes, once got the hang of it is to be preferred.

 

@devadevadev

You are creating yourself a non-existing problem.

If you review your code, at a given point you find (or impose) a "prefix" (C:\Users) and then apply it indiscriminately to all "users" varaibles, thus creating two sets of variables that differ ONLY because of the prefix.

So why not avoiding the duplicate and "assemble" the needed variable/path on the fly?

@echo off
setlocal EnableDelayedExpansion
SET USER=
SET USERDIR=
SET ALL_USERS=
SET ALL_USERSDIR=
SET Counter=0
FOR %%A IN ("Anand" "Kdev" "Someone else") DO (
ECHO %%A
SET USER=%%~A
SET PREFIX=C:\Users\
ECHO USER is !USER! and USER DIRECTORY is !PREFIX!!USER!
SET ALL_USERS=!ALL_USERS!	"!USER!"
SET ALL_USERSDIR=!ALL_USERSDIR!	"!PREFIX!!USER!"
)
SET ALL_USERS
ECHO.

CALL :Parse_Users %ALL_USERS%
ECHO.

GOTO :EOF

:Parse_Users
SET /A Counter+=1
SET User_%Counter%="%~1"
SET User_%Counter%_DIR="!PREFIX!%~1"
SET User_%Counter%

IF NOT "%~2"=="" SHIFT&GOTO :Parse_Users
GOTO :EOF

:duff:

Wonko



#99 devdevadev

devdevadev

    Frequent Member

  • Advanced user
  • 406 posts
  •  
    India

Posted 02 August 2017 - 06:52 PM

I want to execute following command only if 'Removable' variable EXIST/DEFINED. How I can do this ? 

FOR %%A IN (%Removable%) DO CALL :Sort_Rval %%A !VOL_%%A!
FOR /F "tokens=2 Delims==" %%A IN ('SET RFree_') DO SET MostFreeRem=%%A
SET MostFreeRemMB=!VOL_%MostFreeRem%!
SET MostFreeRemMB=%MostFreeRemMB: =%
SET MostFreeRemMB=%MostFreeRemMB:~0,-6%
SET MostFreeRem 

I have tried following ways but it's looking we can't execute multiple commands within IF condition ?

IF DEFINED Removable ( commands )
IF DEFINED Removable DO ( commands )
IF NOT "!Removable!"=="" ( commands )

Any similar example Please !!!



#100 cdob

cdob

    Gold Member

  • Expert
  • 1343 posts

Posted 02 August 2017 - 07:05 PM

it's looking we can't execute multiple commands within IF condition ?

.
Use parenthesis and several lines.
set Removable=true
IF DEFINED Removable ( 
 echo command1
 echo command2
 echo command3
)






Also tagged with one or more of these keywords: cmd, winpe, boot.wim, usb booting, multibooting

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users