无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 4038|回复: 24
打印 上一主题 下一主题

[求助] FOR /F命令求助

[复制链接]
跳转到指定楼层
1#
发表于 2023-10-12 23:48:33 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zts59 于 2023-10-12 23:58 编辑

批处理如下:

@echo off
:start1
set /p user1=输入用户名:
net user %user1% >nul 2>nul && goto next1 || echo 用户不存在.
goto start1
:next1
::获取用户的SID
::wmic useraccount where name="%user1%" get sid
for /f "skip=1" %%i in ('wmic useraccount where name="%user1%" get sid') do SET "USID=%%i"
echo %USID%
::查询用户是否已经登陆
REG QUERY HKEY_USERS /F %USID% /K /E && goto exec1 || goto next2

:next2
::从注册表读取用户注册表文件NTUSER.DAT路径
for /f "skip=1 takens=3" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%usid%" /v ProfileImagePath') do set "u_dat=%%a"
echo %u_dat%
::装载用户注册表
reg load HKEY_USERS\%USID% %u_dat%\ntuser.dat

:exec1
::对用户的注册表操作,外部命令SETACL.EXE要求管理员权限才能执行,对用户注册表的权限进行变更
setacl -on HKEY_USERS\%usid%\Software -ot reg -actn rstchldrn  -rst dacl,sacl
ping 127.0.0.1 -n 3 >nul
reg unlod HKEY_USERS\%usid%


以上是修改用户注册表的批处理
对于FOR中的需要执行的命令一直没有办法成功,好像是要加转义符或别的什么,不知道怎么处理,望高手详解,谢谢

SetACL.zip

242.73 KB, 下载次数: 27, 下载积分: 无忧币 -2

2#
发表于 2023-10-13 07:23:26 | 只看该作者
求助不如看dos /help 十分详细
回复

使用道具 举报

3#
发表于 2023-10-13 08:01:30 | 只看该作者
有时需要分步测试的

我这边试了一下,单独执行wmic useraccount where name="Administrator" get sid 是可以的
但在批处理中就报错了

折衷了一下,先输出到临时文件,就可以正常运行并提取了
@echo off
wmic useraccount where name="Administrator" get sid >ttt.txt
for /f %%i in ('type ttt.txt') do set usid=%%i
echo %usid%
pause

点评

谢谢,之前我也是通过TXT文件中转的  详情 回复 发表于 2023-10-13 09:04
回复

使用道具 举报

4#
发表于 2023-10-13 08:19:12 | 只看该作者
  1. for /f "skip=1 takens=3" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%usid%" /v ProfileImagePath') do set "u_dat=%%a"
复制代码

这句直接就是错别字,应该改为:
  1. for /f "skip=1 tokens=3" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%usid%" /v ProfileImagePath') do set "u_dat=%%a"
复制代码

reg unlod同理。

转义符号我不太会用,给个用临时文件的替代版本。wmic机制好像比较特殊,不能用常理考虑。
  1. wmic useraccount where name="%user1%" get sid | findstr /b S- > "%TEMP%\tmp-123456.txt"
  2. for /f "usebackq" %%i in ("%TEMP%\tmp-123456.txt") do SET USID=%%i
  3. del /s /q /f "%TEMP%\tmp-123456.txt" >nul
复制代码

点评

谢谢详细说明  详情 回复 发表于 2023-10-13 09:03
回复

使用道具 举报

5#
发表于 2023-10-13 08:36:16 | 只看该作者
看文档,分部测试
回复

使用道具 举报

6#
发表于 2023-10-13 08:48:29 | 只看该作者
本帖最后由 dos时代菜鸟 于 2023-10-13 09:00 编辑

注意
1. 用 ^= 替换 =
2.用 SETLOCAL ENABLEDELAYEDEXPANSION
3.wmic 输出的文本流不规范,换行回车有问题,需要再用 for /f 进行重新规范数据。


  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set user1=Administrator
  4. for /f "tokens=1" %%i in ('wmic useraccount where name^="!user1!" get sid') do (
  5.     for /f %%l in ("%%i") do set "USID=%%l"
  6. )
  7. echo "!USID!"
复制代码



点评

谢谢,这个用法一直没有搞懂 试了这个,变量取出来有点问题: E:\temp\txt>test S-1-5-21-1757739531-689602333-1147531500-500 ECHO 处于关闭状态。 请按任意键继续. . . 是否有两个值?后面把前面覆盖了?  详情 回复 发表于 2023-10-13 09:02
回复

使用道具 举报

7#
 楼主| 发表于 2023-10-13 09:00:29 | 只看该作者
谢谢大家,问题解决了
回复

使用道具 举报

8#
发表于 2023-10-13 09:02:01 | 只看该作者
发帖子的人少了
回复

使用道具 举报

9#
 楼主| 发表于 2023-10-13 09:02:46 | 只看该作者
dos时代菜鸟 发表于 2023-10-13 08:48
注意
1. 用 ^= 替换 =
2.用 SETLOCAL ENABLEDELAYEDEXPANSION

谢谢,这个用法一直没有搞懂
试了这个,变量取出来有点问题:
E:\temp\txt>test
S-1-5-21-1757739531-689602333-1147531500-500
ECHO 处于关闭状态。
请按任意键继续. . .

是否有两个值?后面把前面覆盖了?
回复

使用道具 举报

10#
 楼主| 发表于 2023-10-13 09:03:37 | 只看该作者
本帖最后由 zts59 于 2023-10-13 09:06 编辑
sunsea 发表于 2023-10-13 08:19
这句直接就是错别字,应该改为:

reg unlod同理。

谢谢详细说明,你的结果最精确
回复

使用道具 举报

11#
 楼主| 发表于 2023-10-13 09:04:41 | 只看该作者
hilsonma 发表于 2023-10-13 08:01
有时需要分步测试的

我这边试了一下,单独执行wmic useraccount where name="Administrator" get sid 是 ...

谢谢,之前我也是通过TXT文件中转的
回复

使用道具 举报

12#
发表于 2023-10-13 09:09:59 | 只看该作者
本帖最后由 dos时代菜鸟 于 2023-10-13 09:17 编辑
zts59 发表于 2023-10-13 09:02
谢谢,这个用法一直没有搞懂
试了这个,变量取出来有点问题:
E:\temp\txt>test

就是因为 wimc 文本流输出有问题,换行回车 不规范,可以像我刚发的例子中那样,再用一次 for /f 进行文本规范,就可以了。不用提前输出到文件。

  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. set user1=Administrator
  4. for /f "tokens=1" %%i in ('wmic useraccount where name^="!user1!" get sid') do (
  5.     for /f %%l in ("%%i") do (
  6.         set "USID=%%l"
  7.     )
  8. )
  9. echo "!USID!"
  10. pause
复制代码




当然也可以 用计数器,只要 第二行的数据,但是因为 他的 换行回车不规范,很可能把 不规范的换行回车符也赋值到变量,会给此后的变量应用造成隐患。


一般的 只要用 了 for /f 里面设置变量的情况,就要用 setlocal ,你可以简单理解为 用 ! 取代了 % ,避免设置变量时很多混乱的情况。而且 for 内部的变量设置 可以在 for 循环以外被使用。大概就是这个意思吧。

点评

谢谢,看到你修改的了,发现变量值前后带了双引号,这个怎么去掉?  详情 回复 发表于 2023-10-13 09:13
回复

使用道具 举报

13#
 楼主| 发表于 2023-10-13 09:13:49 | 只看该作者
dos时代菜鸟 发表于 2023-10-13 09:09
就是因为 wimc 文本流输出有问题,换行回车 不规范,可以像我刚发的例子中那样,再用一次 for /f 进行文 ...

谢谢,看到你修改的了,发现变量值前后带了双引号,这个怎么去掉?
回复

使用道具 举报

14#
发表于 2023-10-13 09:15:17 | 只看该作者
zts59 发表于 2023-10-13 09:13
谢谢,看到你修改的了,发现变量值前后带了双引号,这个怎么去掉?

就是这句 输出语句 带了 引号而已。与变量本身无关。
echo "!USID!"
回复

使用道具 举报

15#
发表于 2023-10-13 09:27:23 | 只看该作者
for /f "skip=1" %# in ('"wmic useraccount where name="Administrator" get sid|findstr ."') do echo %#
回复

使用道具 举报

16#
发表于 2023-10-13 11:16:55 | 只看该作者
本帖最后由 dos时代菜鸟 于 2023-10-13 11:18 编辑

不需要外部命令 findstr ,而是用 wimc 自带的 /format 参数来规范输出信息,应该也能实现



比如:
  1.     @echo off
  2.     SETLOCAL ENABLEDELAYEDEXPANSION
  3.     set /p user1=请输入账户名:
  4.     for /f "tokens=1,2 delims==" %%c in ('"wmic useraccount where name="!user1!" get sid /format:value 2>nul"') do (
  5.         if /i "%%c"=="sid"  set "sid=%%d"
  6.     )
  7.     if defined sid (echo !sid!) else (echo 用户不存在..)
  8.     pause
复制代码

点评

不错,把用户是否存在也一起判断了,不用NET外部命令了  详情 回复 发表于 2023-10-14 09:03
回复

使用道具 举报

17#
发表于 2023-10-13 11:37:39 | 只看该作者
zts59 发表于 2023-10-13 09:00
谢谢大家,问题解决了

恭喜恭喜问题解决
回复

使用道具 举报

18#
发表于 2023-10-13 12:15:30 | 只看该作者
学习学习
回复

使用道具 举报

19#
 楼主| 发表于 2023-10-14 09:03:58 | 只看该作者
dos时代菜鸟 发表于 2023-10-13 11:16
不需要外部命令 findstr ,而是用 wimc 自带的 /format 参数来规范输出信息,应该也能实现

不错,把用户是否存在也一起判断了,不用NET外部命令了
回复

使用道具 举报

20#
发表于 2023-10-14 09:21:04 来自手机 | 只看该作者
在线修改离线用户的注册表权限?

点评

是啊,此程序是恢复用户注册表权限,不用切换登陆,在当前受限用户下,以其它用户(管理员帐号密码)执行本程序,可以在线修改其他用户(离线或在线)的用户注册表权限。 在公司上班,职员工电脑都是受限用户,为  详情 回复 发表于 2023-10-14 10:59
回复

使用道具 举报

21#
 楼主| 发表于 2023-10-14 10:59:22 | 只看该作者
窄口牛 发表于 2023-10-14 09:21
在线修改离线用户的注册表权限?

是啊,此程序是恢复用户注册表权限,不用切换登陆,在当前受限用户下,以其它用户(管理员帐号密码)执行本程序,可以在线修改其他用户(离线或在线)的用户注册表权限。

在公司上班,职员工电脑都是受限用户,为应付第三方验厂,之前做了一个批处理:验厂时限制注册表和隐藏文件,并限制显示隐藏,删除记录,并限制生成历史记录,
这个是反向操作。

回复

使用道具 举报

22#
发表于 2023-10-14 15:39:06 | 只看该作者
本帖最后由 dos时代菜鸟 于 2023-10-14 16:42 编辑
zts59 发表于 2023-10-14 09:03
不错,把用户是否存在也一起判断了,不用NET外部命令了

其实可以不用手动输入 账户名,可以用选择的



users.7z (532 Bytes, 下载次数: 2)

比如:
  1. @echo off
  2. SETLOCAL ENABLEDELAYEDEXPANSION
  3. :start1
  4. cls
  5. set n=0
  6. echo ===本地账户列表========================================================================
  7. for /f "tokens=2,3 delims=," %%c in ('"wmic useraccount  get name,sid,status /format:csv"') do (
  8.     if not "%%d"=="" ( if /i not "%%d"=="sid" ( set /a n+=1 && echo !n!    %%c  && set "sid_!n!=%%d"))
  9. )
  10. echo ----------------------------------------------------------------------------------------
  11. set /p m=请选择一个账号(1-!n!,0退出):
  12. if !m! equ 0 goto :eof
  13. if not  defined sid_!m! (
  14.     echo 用户不存在,按任意键重新选择.... && pause >nul &&  goto start1
  15. ) else (
  16.     for %%m in (!m!) do ( set "usid=!sid_%%m!" && echo !usid! )
  17. )
  18. pause
复制代码
回复

使用道具 举报

23#
发表于 2023-11-15 21:47:00 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

24#
发表于 2023-11-16 08:44:51 | 只看该作者
为什么说cmd 不好呢。

1: windows 本身的路径符用了反斜杠,这与通用的 转义符"\" 正好冲突。至于为什么不用正斜杠,据说是为了兼容远古老系统。我记忆中现在的 FileOpen 函数是支持正斜杠的。

2:   批处理用的 转义符"^" 这又与正则的 “^" 字符冲突。
3:   windows 的变量表达方式是 %var% 而不像其它脚本常用的 $. 这也没啥,但碰到需要环境扩展的时候就要用到 %% 甚至是 %%%%  %%%%%%%%%% 这让人很崩溃。
4:  cmd 原生不支持 `cmds`  的子环境输出,只能用 for /f 或 重定向到文件实现。用到 for /f 的时候麻烦又来了,要是命令中有 双引号,又得转义.   我印象中可以有   ^" "" \" 等转义方法,而且一般只有一种可用。
5: windows 的 \r\n 又是一大神坑。

还有各种麻烦,有些甚至难以解决。当年的windows 是一家独大的,标新立异变成现在的一堆堆坑。
回复

使用道具 举报

25#
发表于 2024-2-22 21:26:26 | 只看该作者
学习学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-15 11:56

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表