Posts Tagged ‘dos’

DFS Replication Validation Script…

December 13th, 2012 by Jeremy Pavlov | No Comments | Filed in Microsoft, Microsoft Infrastructure, Scripting, VMware, VMware ESXi

The other day, while at the enterprise-level customer with whom I’m currently working, I ran into a situation where I needed to validate that certain parts of a DFS hierarchy were properly being replicated across the customer’s AD domain controllers.  As the administrators applied normal, routine DFS changes, the changes sometimes didn’t replicate properly across the enterprise — causing some segments of the DFS structure to not be visible or available. 

Apparently, the DFS problem was a result of using VMware guests as AD DCs.  I understand (from the customer) that a Microsoft hotfix is in the last stages of testing (at the time of this writing) and will be available for release “soon.”   It seemed that even though the DCs in question did not synchronize time with the ESX host upon which they reside, there is a default behavior in VMware Tools that assigns the host time value to the guest — at least up until the “do not sync” routine is processed during startup; after which the guest is then allowed to find its own time.  During this brief time window, the DFS Namespace service sometimes completes assembling its DFS target list and can find itself behind in time, relative to links it has been given by PDCE; which makes no sense to it, and it removes them from its listing.  And as a result, people can’t find their mapped drives or browse some of the DFS Tree.  (Note: I cannot take credit for this timing behavior investigation and results; and while I’d love to credit the folks who are due, I’m not permitted to.)  The customer remedied the situation with a temporary fix, but the real fix is the up-coming aforementioned patch.

Anyway, while the symptoms were being analyzed, I was working on other things and needed to work around the issue as much as possible while the solution was being chased.  So, I whipped up a simple little DOS script to go out and validate the top-levels of the DFS hierarchy across all domain controllers that carry them, in order to find out what would or wouldn’t be properly resolved.

For what it’s worth, I thought I’d pass the script along to you.  Here it is:

 

@SETLOCAL ENABLEDELAYEDEXPANSION
@set AdDomain=MyAdDomain.local
@set DirQuantity=17
@set DestPath=h:\DcList.txt
@REM This requires elevated credentials, otherwise will fail...
@ipconfig /flushdns
@REM First we build the input file...
@nslookup %AdDomain% |findstr [0-9].*.[0-9].*|findstr /V /C:"Address: " > %DestPath%
@ECHO As of 20121212, there should be %DirQuantity% DFS dirs on each server (actual, plus the "." and ".." items).
@REM Now loop through the input file and check the DFS at the destination...
@For /F "tokens=*" %%Q in (%DestPath%) Do @(
@set MYDC=%%Q
@set MYDC=!MYDC:Addresses:  =!
for /f "tokens=* delims=" %%A in ('dir /A:D \\!MYDC!\Corp ^|findstr /C:"Dir(s)"') do @set MYDIR=%%A
for /f "tokens=* delims= " %%G in ("!MYDIR!") do @set MYDIR=%%G
@REM Options A: Use this line if you wish to see all DFS sources:
@ECHO For: !MYDC!  	!MYDIR:~0,9!
@REM Option B: Use this line if you wish to see only those in violation 
@REM (note: there's a space and tab separator for spacing alignment):
@REM @ECHO For: !MYDC!  	!MYDIR:~0,9! |findstr /V /C:"%DirQuantity% Dir(s)"
)

What it does:

The script builds a domain controller list in a static, external file, then iterates through the list, attempting to quantify the available DFS path branches against a numeric count that you supply in another variable.  I provided two different “ends” to the script (one of them commented out), in order to give you a couple different ways to present the results.  Make sure to “set” the variables in the first few lines, to your locally-relevant information; especially the number of *expected* DFS hierarchies.

Of course, I wanted to write it to do more, but I pretty much ran up against the limits of what I *should* do in a DOS script.  I’ll make another version in PowerShell some day that iterates down the hierarchy and validates the entire structure, instead of just the top level… 

…Unless you beat me to it…  ;)

There you go; enjoy!

:)

 

 

Did you like this? Share it:

Tags: , , , , , , ,

XP DOS Batch File Date Tip…

August 16th, 2012 by Jeremy Pavlov | No Comments | Filed in Microsoft, Scripting

A little while back, I wrote this tip on DOS Batch File Date Tips for Windows 7 and Server 2008.  I was asked for a clarification for XP as well (due to the minor differences), so I’m writing this as an alternate version of the same previous post.

No matter what people think, DOS batch scripts are just as alive and needed as ever.  And for all the tasks we create on Windows servers, we still commonly need to gather application output, rotate logs, etc.

So when running a script that exports results to a log/results file, I always prefer to date my file names for easy tracking and history.  My preferred date arrangement for filenames is the date in reverse format: YYYYMMDD, or 20120809.  And since the DOS date command isn’t as friendly or flexible as the Linux/Unix date command (with which you may easily format the output in myriad ways), it’s best to do the next-best thing: use the date *variable*.

Most folks don’t even know that your Windows system is keeping a real-time variable for the date, but it certainly makes sense that it would be necessary.  Go ahead, pull up a command prompt and type: echo %date%

…and on a Windows XP workstation, you’ll get a result like this: 08/09/2012

So what we need to do now is to utilize string manipulation, grab the date elements we want, and flip the order around to get the arrangement we need:
set todaysdate=%date:~6,4%%date:~0,2%%date:~3,2%

The structure above is this: There are 3 sections, all of which use the date variable.  The first section moves in 6 characters, and grabs 4 for the year.  The second starts at 0 (zero, the beginning) characters and grabs 2 (for the month), and the third moves in 3 and grabs 2 (for the day).  As a result, we have reverse-date!

Then we can set a variable to use the combined date variable in the filename like this:

set exportfile=C:\temp\export\myexport-%todaysdate%.txt

…now just call the %exportfile% in your batch file when you redirect your output, and viola!!  Here’s what it looks like when you echo %exportfile%:

C:\temp\export\myexport-20120809.txt

Enjoy…

8-)

 

 

Did you like this? Share it:

Tags: , , ,

DOS Batch File Error Level Checking Tricks…

June 28th, 2012 by Jeremy Pavlov | 2 Comments | Filed in Scripting, Windows 7

Fellow Coreteker Paul and I were chatting today about capturing post-execution error codes in Windows.  Paul was looking to grab the error code resulting from a script (VBscript, if I recall), and he was looking for the best way.  He found a handy way to handle it (pun intended); but it left me thinking about how one might capture error codes *within* a DOS batch file, and how that might be tricky.  So I tossed a few notes together and I thought I’d pass them along to you… 

First things first: the DOS post-execution error code is stored in the dynamic variable %errorlevel%

One of the important things to remember when trying to grab error codes from DOS batch files is that each executed line of the batch file will produce its own error code result, as well as the fact that you have the capability to grab the error code of the script as a whole (by issuing an EXIT /B command).  Note that one must never hard-set an error level, as you’ll break the shell’s ability to dynamically manage the variable.

 So, if you have multiple lines in your script and wish to capture the error codes from some of the lines, here are a few suggestions…

IF %ERRORLEVEL% EQU 0 SET RESULT=YUUUP

…this will grab your error code and just for fun set your %RESULT% to the now-famous trademarked “Storage Wars” catch phrase (minus the exclamation point for legal).  You’d typically run this line after the previous line from which you wanted to capture the code.  Error code of zero almost always means that it is operating as intended. 

However, to catch unintended errors in either of these cases,

IF %ERRORLEVEL% NEQ 0 SET RESULT=%ERRORLEVEL%
IF %ERRORLEVEL% EQU 1 SET RESULT=%ERRORLEVEL%

…they will both will grab the error code, check to see if it’s not equal to zero, and set the %RESULT% variable with the code it grabbed.  Note that the second line — while checking for a value of 1 — is actually checking for 1 or more; this is default behavior.

After grabbing the error code and evaluating it, you can have the script have success/failure-specific condition statements act upon the condition (send notice, add to the event log, exit, etc.).

I hope that helps!

 

Did you like this? Share it:

Tags: , , , , ,

Windows 7 and Server 2008 DOS Batch File Date Tip….

May 31st, 2012 by Jeremy Pavlov | 2 Comments | Filed in Microsoft, Scripting, Windows 7

No matter what people think, DOS batch scripts are just as alive and needed as ever.  And for all the tasks we create on Windows servers, we still commonly need to gather application output, rotate logs, etc.

So when running a script that exports results to a log/results file, I always prefer to date my file names for easy tracking and history.  My preferred date arrangement for filenames is the date in reverse format: YYYYMMDD, or 20120531.  And since the DOS date command isn’t as friendly or flexible as the Linux/Unix date command (with which you may easily format the output in myriad ways), it’s best to do the next-best thing: use the date *variable*.

Most folks don’t even know that your Windows system is keeping a real-time variable for the date, but it certainly makes sense that it would be necessary.  Go ahead, pull up a command prompt and type: echo %date%

…and on Windows 7 and Server 2008 (for XP, please see this post), you’ll get a result like this:  Wed 05/31/2012

 So what we need to do now is to utilize string manipulation, grab the date elements we want, and flip the order around to get the arrangement we need:
set todaysdate=%date:~10,4%%date:~4,2%%date:~7,2%

 The structure above is this:  There are 3 sections, all of which use the date variable.  The first section moves in 10 characters, and grabs 4.  The second moves in 4 characters and grabs 2, and the third moves in 7 and grabs 2.  As a result, we have reverse-date!

Then set a variable to use the combined date variable in the filename.

set exportfile=C:\temp\export\myexport-%todaysdate%.txt

…now just call the %exportfile% in your batch file when you redirect your output, and viola!!  Here’s what it looks like when you echo %exportfile%:

C:\temp\export\myexport-20120531.txt

Enjoy…

8-)

(Updated 20120809 for OS version clarification)

Did you like this? Share it:

Tags: , , ,

More DOS batch file fun…

April 19th, 2012 by Jeremy Pavlov | No Comments | Filed in Microsoft, Scripting

Subtitle: “Getting more precise and limited output from FindStr results against multiple files…” …which is a lousy subtitle, I know.

Sometimes, you just want to parse multiple files in a folder for particular lines of content, and do something with those parsed results (perhaps dump to file, or use as input for a loop). However, one of the challenges can be that while using FindStr against multiple files, the output shows the source filename on the line with the result as a courtesy (thanks a lot). And lacking Linux-like flexibility of control over the command options, we’re almost out of luck before we ever start — but there are ways around that… First, however, I’ll demonstrate the challenge.

DOS is Not Linux

Starting out with a test folder, containing two text files each with a few lines we want, and few we don’t.

C:\Test>dir /B
file.wri
other.wri

Assume that we are looking for any line in these files that contains the tar command; so using findstr, we issue our search:

C:\Test>findstr /C:"tar " *.wri

…and as described, the result shows the filename on each line:

file.wri:tar this
file.wri:tar that
other.wri:tar some other stuff
other.wri:#commented out tar thingy

This would not be good if we were trying to take the results as issued commands or as input to other commands. So, we’ll try to meet findstr on its own terms, and using good ol’ type and try to mask the fact that we are sending individual files to findstr.

So piping the one into the other, we issue the command:

C:\Test>type *.wri |findstr /C:"tar "

…and the the result is just goofy:

file.wri

other.wri

tar this
tar that
not a line you want tar some other stuff
#commented out tar thingy

But DOS Loops Rule

But all hope is not lost. If we loop through all the files individually, and stuff them each into findstr one-by-one with each iteration of the loop, findstr will be happy and give us pretty, clean, limited output. Yay! Just put this in a script to see what I mean:

@ECHO OFF
@For /F "tokens=*" %%Q in ('dir /B c:\test\*.wri') Do @(
findstr /C:"tar " %%Q
)

…and of course, the result is exactly what I wanted:

tar this
tar that
tar some other stuff
#commented out tar thingy

Enjoy!

Did you like this? Share it:

Tags: , , , , , ,

Remotely Reboot a Bunch of XP Workstations…

April 5th, 2012 by Jeremy Pavlov | 2 Comments | Filed in Computer Support, Desktop Management, Desktop OS, Microsoft, Windows 7

I got an interesting question from a co-worker today (we’ll call him “Ray” to protect his identity).  Ray wanted to know if it’s possible for his customer to reboot a bunch of workstations at once, in a way other than the customer’s workstation management system. 

The customer is in the midst of a major migration from XP to Windows 7, and simultaneously from Novell ZENworks 7 to Novell ZCM 11.  Ray’s team has put together an amazing set of automatic deployment steps that take the ZENworks-controlled XP machine all the way to a completely-deployed, domain-managed, ZCM-controlled Win 7 machine with all needed applications installed, via a method called “Zero Touch Deployment”.   And it all kicks off with a reboot — but the only problem is that the bundled reboot in the old ZENworks is not always reliable.

Note: This particular customer’s machines are XP, all in one domain, all are resolvable (either via WINS or DNS), and can all be managed by a single set of credentials; allowing remote administrative execution and permitting the following to work.

So when Ray asked the question, I said, “Absolutely!”  I can do that, and not even break out PowerShell (or bash, for that matter).  Ray had nothing more than a list of computer names, but that is all we need.  Let’s do it old-school, with a DOS batch “for” loop.  Man, I love my job… 

First, the input file; it is just a single list of computer names or IP addresses, one-per-line, in a TXT file.  We put them in a file called C:\TEMP\RemoteRebooter-Input.txt, and here’s a varied example of how it might look:

pc1
10.2.1.3
wks22.domain.local
192.168.33.44
amyscomputer

The script is a bit on the simple side, but does the job.  I call this RemoteRebooter.bat, and notice that it calls the other input file by name:

@ECHO OFF
@Echo Process RemoteRebooter...
@For /F "tokens=*" %%Q in (c:\temp\RemoteRebooter-Input.txt) Do @(
1>&2 ECHO Rebooting: %%Q
shutdown -m \\%%Q -r -f -t 20 -c "Rebooting in 20 seconds via %0 -- please save your work quickly."
)
1>&2 type nul
@ECHO Complete!

If you need details on the shutdown flags, type shutdown /? into a command prompt.  And I’m not sure if I should mention it here, but if you want this to work on Windows 7, you have to change the syntax a bit, flipping hyphens (-) to slashes (/).  And of course, this is only one way of doing it, and I know you all have others. 

Make sure to drop a comment and tell us how *you* do it!

 

 

 

Did you like this? Share it:

Tags: , , , , , , , , , , ,