Looks like Squashman did a nice explanation as I was typing this.

Here's my version anyways.
A For loop looks at
each line of text generated by what ever is in the
In (...) part.
It splits the line of text into pieces (tokens) using the specified delimiters.
So the command (Number 4) is run, Findstr restricts the output to one line of text containing Percent File Fragmentation, and that is what is returned to the For loop:
Code:
Percent file fragmentation = 0 %
I'm using
two delimiters (Delims=
=^%
%), the Equals sign and the Percent sign. The percent sign has to be doubled in a batch file, and the caret escapes it so it won't be mistaken for the start of a variable to be expanded.
I included the percent sign as a delimiter to easily remove the percent symbol at the end of the line.
This will split the line into these two parts (>< symbols added to show the spaces):
- > Percent file fragmentation <
- > 0 <
Tokens=tells the For loop which pieces (tokens) to get from the parsed line. 1,2 means get the first and second tokens;%%A=#1 and %%B=#2
from each line. (This will also work if you use Tokens=2, then %%A will be given the value of token #2). The Findstr part limits the output to just one line, so all the other lines aren't split by the For loop, they are ignored.
I started with the tokens=1,2 because I was initially going to use an If statement to find the
Percent file fragmentation part in %%A, then assign the %%B token to the variable, then realized I'd still have to remove the leading/trailing spaces from %%A to do the match. So decided to use Findstr to find the line.
Just didn't bother to change it to tokens=2.
I used Set /A rather than just Set because it has the side benefit of removing the leading and trailing spaces around the 0.
I don't know why it would lock the system.
Defrag has to be run from an Admin command prompt. If you run in a normal prompt, it should just display an error, then continue with the If statement. _PercentFrag would be undefined (unless it has a value from a previous run) so the If statement should fail and abort the batch file. If it does have a value and it's over 15, it will run Defrag, but either case shouldn't lock the system
Mine took about 3 minutes then told me it was 3% fragmented (Vista Ultimate x86 running in VPC), and about 5 minutes and 4% on my laptop running Vista Home Premium x64. Neither one locked up.
You might try directing the output to a temp text file, then read the text file in the For loop to see if that makes a difference:
Code:
>DFreport.txt defrag %systemdrive% -a -v
For /F "Tokens=2 Delims==^%%" %%A In ('type DFreport.txt^|Findstr /I /C:"Percent File Fragmentation"') Do Set /A _PercentFrag=%%A
If you can get Task Manger open when it freezes like that, you can end the cmd.exe process.
Note that this won't work on XP, the wording in the report is different. XP lists 3 different fragmentation percentages, so you'd have to check which OS is running and modify the Findstr string accordingly. You'd have to pick which one to check. Here's what my XP system displays:
Code:
Volume fragmentation
Total fragmentation = 2 %
File fragmentation = 5 %
Free space fragmentation = 0 %
Though if you search for just
file fragmentation, it will work for both Vista and XP.