Search code examples
batch-filecmdsubinacl

Multi line variable in batch file echoing back hidden spaces in printer permission script


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


Solution

  • 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
      )
    )