how do I manage to demand the result obtained in the for?
@echo off
setlocal
setlocal EnableExtensions
setlocal EnableDelayedExpansion
set "usr1_name=user1"
for /F "skip=1 delims= " %%a in ('wmic useraccount where name^="%usr1_name%" get passwordexpires') do (
set usr1_passwdexpiretmp=%%a
)
for /F "skip=1 delims= " %%b in ('wmic useraccount where name^="%usr1_name%" get passwordchangeable') do (
set usr1_passwordchangeabletmp=%%b
)
echo %usr1_passwdexpiretmp%
echo %usr1_passwordchangeabletmp%
pause
Result:
ECHO It's deactivated
ECHO It's deactivated
Print Result in Variable Obtained by for
Moderator: DosItHelp
-
- Expert
- Posts: 1166
- Joined: 06 Sep 2013 21:28
- Location: Virginia, United States
Re: Print Result in Variable Obtained by for
You've enabled delayed expansion, but you aren't using it. Change the echo statements to
Code: Select all
echo !usr1_passwdexpiretmp!
echo !usr1_passwordchangeabletmp!
-
- Posts: 14
- Joined: 26 Oct 2017 11:30
Re: Print Result in Variable Obtained by for
I made the exchange and yet the return is:ShadowThief wrote: ↑28 Aug 2018 14:54You've enabled delayed expansion, but you aren't using it. Change the echo statements toCode: Select all
echo !usr1_passwdexpiretmp! echo !usr1_passwordchangeabletmp!
ECHO It's deactivated
ECHO It's deactivated
I disable delayed expansion and still the return is:
ECHO It's deactivated
ECHO It's deactivated
Re: Print Result in Variable Obtained by for
The ECHO statements are not within the FOR loop, so delayed expansion is not required.
Assuming your code really matches your post, the most likely explanation is that user "user1" does not exist, so there are no iterations and the variables are never set.
It is easy to check - simply add echo %%a within the first FOR loop. If you don't see a value printed when you run the script, then you know the user does not exist.
Dave Benham
Assuming your code really matches your post, the most likely explanation is that user "user1" does not exist, so there are no iterations and the variables are never set.
It is easy to check - simply add echo %%a within the first FOR loop. If you don't see a value printed when you run the script, then you know the user does not exist.
Dave Benham
-
- Posts: 14
- Joined: 26 Oct 2017 11:30
Re: Print Result in Variable Obtained by for
I'm considering that the user exists, and I test the script on a Windows with that created user, follows the piece of script that I want to make work, when trying to execute it the return is:dbenham wrote: ↑29 Aug 2018 06:47The ECHO statements are not within the FOR loop, so delayed expansion is not required.
Assuming your code really matches your post, the most likely explanation is that user "user1" does not exist, so there are no iterations and the variables are never set.
It is easy to check - simply add echo %%a within the first FOR loop. If you don't see a value printed when you run the script, then you know the user does not exist.
Dave Benham
ECHO It's deactivated
ECHO It's deactivated
if I run "echo %%a" and "echo %%B" I get the result I want, but I need to save the result in a variable that will be used later
@echo off
set "usr1_name=user1"
set "usr1_status=yes"
set "net=%windir%\System32\net.exe"
:start
if /i "%usr1_status%" == "yes" (
%net% user "%usr1_name%" 1>nul 2>nul
if not errorlevel 1 (
for /f "skip=1 delims= " %%b in ('wmic useraccount where name^="%usr1_name%" get passwordchangeable') do (
if /i "%%b" == "true" (
set "usr1_passwordchangeabletmp=yes"
) else if /i "%%b" == "false" (
set "usr1_passwordchangeabletmp=no"
)
)
for /f "skip=1 delims= " %%a in ('wmic useraccount where name^="%usr1_name%" get passwordexpires') do (
if /i "%%a" == "true" (
set "usr1_passwdexpiretmp=yes"
) else if /i "%%a" == "false" (
set "usr1_passwdexpiretmp=no"
)
)
echo %usr1_passwordchangeabletmp%
echo %usr1_passwdexpiretmp%
goto exit
) else (
goto exit
)
) else if /i "%usr1_status%" == "no" (
goto exit
)
:exit
pause
Re: Print Result in Variable Obtained by for
That's because WMIC outputs in Unicode, FOR /F converts it to ANSI encoding but before that, it will strip the LineFeeds and splits the output to individual lines then converts the text, the result is that you end up with orphaned carriage return characters.
So the last line that FOR /F passes to the body is a single carriage return character which will be stripped again by batch parser when using normal expansion, so essentially echo %usr1_passwdexpiretmp% will become just echo with no parameters and you will get ECHO in on/off message, and even if you use delayed expansion, echo prints the CR character which will just moves cursor to the start of the line.
There are multiple ways to overcome this, some are slightly simpler than the others, but will just work if certain conditions are met and output is in some particular format, but i'll prefer more general approach which should not depend on the format and value of the properties you query.
A Simple method which will only work if the value you query does not contain any of these characters: <SPACE>;, which will work for your particular query anyway
And a more general approach which will work for most cases
It still is not bullet proof and will fail if the value you query contains double quotes and any batch poison character exist inside the double quotes like "this & that" then when using the last set to strip the CR character this fails: set "value="this & that""
This can happen for example when querying Processes CommandLine values.
So the last line that FOR /F passes to the body is a single carriage return character which will be stripped again by batch parser when using normal expansion, so essentially echo %usr1_passwdexpiretmp% will become just echo with no parameters and you will get ECHO in on/off message, and even if you use delayed expansion, echo prints the CR character which will just moves cursor to the start of the line.
There are multiple ways to overcome this, some are slightly simpler than the others, but will just work if certain conditions are met and output is in some particular format, but i'll prefer more general approach which should not depend on the format and value of the properties you query.
A Simple method which will only work if the value you query does not contain any of these characters: <SPACE>;, which will work for your particular query anyway
Code: Select all
for /f "skip=1 delims=" %%A in ('wmic useraccount where name^="%usr1_name%" get passwordexpires') do for %%B in (%%A) do set "usr1_passwdexpiretmp=%%B"
Code: Select all
@echo off
setlocal EnableExtensions
set "usr1_name=user1"
for /f "tokens=1* delims==" %%A in ('wmic useraccount where name^="%usr1_name%" get passwordexpires /value') do (
if "%%B" NEQ "" set "usr1_passwdexpiretmp=%%B"
)
:: usr1_passwdexpiretmp still contains carriage return, strip it by reassigning with normal expansion
set "usr1_passwdexpiretmp=%usr1_passwdexpiretmp%"
echo %usr1_passwdexpiretmp%
This can happen for example when querying Processes CommandLine values.
-
- Posts: 14
- Joined: 26 Oct 2017 11:30
Re: Print Result in Variable Obtained by for
Funny that testing only the code I get the result, but when inserting a for inside the if I get echo offsst wrote: ↑29 Aug 2018 14:14That's because WMIC outputs in Unicode, FOR /F converts it to ANSI encoding but before that, it will strip the LineFeeds and splits the output to individual lines then converts the text, the result is that you end up with orphaned carriage return characters.
So the last line that FOR /F passes to the body is a single carriage return character which will be stripped again by batch parser when using normal expansion, so essentially echo %usr1_passwdexpiretmp% will become just echo with no parameters and you will get ECHO in on/off message, and even if you use delayed expansion, echo prints the CR character which will just moves cursor to the start of the line.
There are multiple ways to overcome this, some are slightly simpler than the others, but will just work if certain conditions are met and output is in some particular format, but i'll prefer more general approach which should not depend on the format and value of the properties you query.
A Simple method which will only work if the value you query does not contain any of these characters: <SPACE>;, which will work for your particular query anywayAnd a more general approach which will work for most casesCode: Select all
for /f "skip=1 delims=" %%A in ('wmic useraccount where name^="%usr1_name%" get passwordexpires') do for %%B in (%%A) do set "usr1_passwdexpiretmp=%%B"
It still is not bullet proof and will fail if the value you query contains double quotes and any batch poison character exist inside the double quotes like "this & that" then when using the last set to strip the CR character this fails: set "value="this & that""Code: Select all
@echo off setlocal EnableExtensions set "usr1_name=user1" for /f "tokens=1* delims==" %%A in ('wmic useraccount where name^="%usr1_name%" get passwordexpires /value') do ( if "%%B" NEQ "" set "usr1_passwdexpiretmp=%%B" ) :: usr1_passwdexpiretmp still contains carriage return, strip it by reassigning with normal expansion set "usr1_passwdexpiretmp=%usr1_passwdexpiretmp%" echo %usr1_passwdexpiretmp%
This can happen for example when querying Processes CommandLine values.