0

I sat down hours ago to write a seemingly straight forward 1 or 2 liner to add permissions to every print queue on a computer using a combination of WMIC and subinacl.exe.

@echo off
pushd %~dp0
setlocal EnableDelayedExpansion
for /f "skip=1 tokens=*" %%a in ('wmic printer get name') do (
set "_var=%%a" do (
for /f "tokens=1,* delims=" %%g in ("!_var!") do (
echo subinacl /printer "%%g" /grant=Everyone=F
    )
)
pause

Turns out it aint so easy at all! This is as close to working I can get, but the echoing reveals extra spaces and quotations in the wrong places, causing sunbinacl to fail with printer name errors, this is the output: -

subinacl /printer "Canon MG5300 series Printer WS  " /grant=Everyone=F
subinacl /printer "testfff                         " /grant=Everyone=F
subinacl /printer "OneNote (Desktop)               " /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF          " /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer     " /grant=Everyone=F
subinacl /printer "444444444444444                 " /grant=Everyone=F
Press any key to continue . . .

This is how it should look for subincal to correctly apply the permissions...

subinacl /printer "Canon MG5300 series Printer WS" /grant=Everyone=F
subinacl /printer "testfff" /grant=Everyone=F
subinacl /printer "OneNote (Desktop)" /grant=Everyone=F
subinacl /printer "Microsoft Print to PDF" /grant=Everyone=F
subinacl /printer "Canon MG5300 series Printer" /grant=Everyone=F
subinacl /printer "444444444444444" /grant=Everyone=F
Press any key to continue . . .

How can I alter my script to achieve the correct spacing and quotations around the printer name like above. I believe I should be able to do this, no problem, but I'm missing something - probably obvious.

I have a feeling it has to do with taking the parsed WMIC output being set as a variable in one block, where perhaps each line of the variable (printer queue) needs to be sent into the subinacl command one by one.

Usually I can get to where I want to be in these instances but cant surpass this issue. Any pointers would be greatly appreciated. Thanks

Tika9o9
  • 405
  • 4
  • 22

3 Answers3

2

This is because wmic formats the strings for a nice table output on screen by filling too short strings with spaces.

Easy to avoid. Just change the formatting.

Change ... ('wmic printer get name') ... to

... ('wmic printer get name /format:list') ...

You don't need to set a variable to use in the inner loop, you can just use the metavariable from the outer loop (you need the second loop though to get rid of the ugly wmic format with a CRCRLF line ending. There are other methods, but a for loop is the most general and safest):

@echo off
pushd %~dp0
setlocal 
for /f "tokens=1* delims==" %%a in ('wmic printer get name /format:list ^|find "="') do (
  for /f "tokens=1,* delims=" %%g in ("%%b") do (
    echo subinacl /printer "%%g" /grant=Everyone=F
  )
)
Stephan
  • 53,940
  • 10
  • 58
  • 91
  • I've seen some WMIC commands with wild unicode outputs so when the font and text looked ok in this case I completely over looked formatting as culprit. Got stuck in a dead end loop trying to clear them using tokens, delims and extra variables! Thanks very much, lessoned learned! – Tika9o9 Jul 13 '23 at 06:59
  • 1
    Piping to `find` converts to ASCII, but doesn't remove the `CRCRLF`. Parsing or setting to a variable removes `CRLF` and leaves the string with an annoying `CR` at the end. The line ending can be removed with a `for` loop, but it keeps the UTF16 format. So using a combination to get "the best from both worlds" – Stephan Jul 13 '23 at 07:40
0

[untested]

...
  for /f "tokens=1,* delims=" %%g in ("!_var!") do (
  set "_printer=%%g"
  call :trim
  echo subinacl /printer "!_printer!" /grant=Everyone=F
    )
)
pause

goto :eof

:trim
if "%_printer:~-1%"==" " set "_printer=%_printer:~0,-1%"&goto trim
goto :eof
  • assign printername to _printer and execute :trim as a subroutine (hence the goto :eof which prevents flow-through to the subroutine)

:trim simply checks the last character of _printer and if it is a space, trims it off and repeats the operation until the trailing spaces are gone.

Repeat : untested

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

To fulfil your tag, and one or two liner requirements, here's a single line example which can be run directly in a Command Prompt, (cmd.exe), window:

for /f tokens^=6^ delims^=^" %g in ('wmic printer get name /format:mof 2^>nul') do @subinacl /printer "%g" /grant=everyone=F

For robust and efficient code, you should, however, use the fully qualified and absolute paths, with extensions, for both of your executable utilities.

Compo
  • 36,585
  • 5
  • 27
  • 39