How to script “Ownership” of NTFS File Systems…

2017-07-27T00:01:07+00:00 July 25th, 2012|Uncategorized|

There’s a time in every IT professional’s life where he or she will need to “Take Ownership” of files and folders that reside on an NTFS File Server (or in larger cases with hundreds or thousands of servers) in a Windows Server 2008 R2 or Windows 7 environment.  I’m sure most IT professionals already know how to do this in the Windows Explorer GUI … but what if your task at hand required that you script this process to run during a limited window of time given during a server migration, and you had to minimize the amount of “clicks” as well as the amount of time spent on multiple servers?  

I was recently assigned to a project very similar to the scenario described above; and after a little research, I stumbled upon a little-known Microsoft tool called ‘takeown.exe’ that has been shipping with Microsoft Server products since Windows Server 2003.  Within minutes of discovering ‘takeown.exe’ I had a script written and I was running it in my test environment with positive results.  This shows how simple the tool really is!

Below is the usage example as seen from the command line ‘takeown.exe /?’:

TAKEOWN 
[/S system [/U username [/P
[password]]]] /F filename [/A] [/R [/D prompt]]

Below is my personally recommended example: 

TAKEOWN.exe /F C:MyFolder /R /A

 

As expressed above, my suggestions are to use the /F (to specify the folder to apply ownership on), the /R switch (as in “recursive” which mean to apply to all child objects, sub-folders and files) and the /A switch (which gives ownership to the “Administrators” group instead of the currently logged in user).  And while I didn’t use the /D switch in the above example, it may be necessary to use the “/D Y” to avoid being prompted in cases where the user ID running the command does not have rights to list the folders.   

You can also reference additional parameters by typing in ‘takeown.exe /?’ from the command prompt on any Windows Server 2008 R2 server or Windows 7 machine.

 

Send an Email from the Windows Commmand Prompt or Script…

2017-07-27T00:01:07+00:00 July 18th, 2012|Uncategorized|

Today, Avi and I were discussing one of the requirements of an application he’s working on;  it seemed simple enough at first blush…

He needed to send an email from a Windows 7 computer — which is fairly straightforward if you happen to have something like BLAT installed, or if you’re able to script a call to a nearby SMTP gateway.  However, there was one major requirement this time:  it had to appear to come from the *user* of the application, with the user’s intent/blessing/permission. 

Yes, Avi could have configured the application to make a direct call to the local email client executable — if there were guaranteed to be one (not necessarily the case), and if the version/type were to be predictable (it might be Outlook, it might be GroupWise, etc.) to properly call with the correct options and flags.  Avi did some digging and soon found a way to get a fully formatted message to launch in Outlook, but we had to modify it a tad to get it to work in both GroupWise and Outlook (and perhaps others).  Here’s what we settled on, and how it works…

Aside: I’ll have to assume that your GroupWise or Outlook is properly installed and configured for these things to work.

Let’s start with the basics (pun intended); this should launch your email client and pre-populate the recipient (interestingly, it should work no matter whether your email client is configured or not):

start mailto:sales@CoretekServices.com

…but you knew that, and you’re clearly not impressed.  Now perhaps the trickiest part: after the recipient in the command — and before the next component (I use Subject in this example) — it is best to use a question (?) mark here for Outlook *and* GroupWise compatibility, although a caret+ampersand (^&) will work if using Outlook only (note that the “%20” is a space character):

start mailto:sales@CoretekServices.com?Subject=Your%20Subject...

…and now you’re intrigued.  Let’s build on that.  Next, we tack on another option in the command (I show the CC option here), separated with a caret+ampersand (^&) :

start mailto:sales@CoretekServices.com?Subject=Your%20Subject...^&CC=questions@YourLinuxGuy.com

…and now I’ve won you over.  Cool!  Let’s complete the line — separated by more caret+ampersand (^&) characters, of course — and make it a fully populated email, ready-to-send:

start mailto:sales@CoretekServices.com?Subject=Your%20Subject...^&CC=careers@CoretekServices.com^&BCC=secret@CoretekServices.com^&Body=This%20is%20the%20message,%20which%20I%20agree%20to%20send%20by%20clicking%20SEND.

Now click send, and enjoy!

 

 

DOS Batch File Error Level Checking Tricks…

2012-06-27T23:01:24+00:00 June 27th, 2012|Uncategorized|

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!

 

The Modify or Alter Column Statements, and MS SQL 2008…

2017-07-27T00:01:07+00:00 June 13th, 2012|Uncategorized|

(…with technical guidance from Avi Moskovitz…)

Recently, I needed to change the width of a column in the SQL Server portion of one of our Databases using MS Management Studio 2008.  And while this meant changing data type, you’d think it would be as easy as simply changing the properties within the table in the same manner that you can within Access 2010; normally, less than one minute to get ‘er done.  And in organizations where it is permissible to un-check the “Prevent saving changes that require table re-creation” on production systems, this might well be the case  (as in the graphic below).

 

The "Prevent saving changes that require table re-creation" option

The "Prevent saving changes that require table re-creation" option

 

But, in my situation, I had to find another route; this was going to require scripting…

1 – A Wild Goose Chase

A few quick searches of things like, “How do you change the width of a column in SQL”, and the results put a big grin across my face — I found reference to a MODIFY statement with an example of a column width change:

ALTER TABLE my_table MODIFY this_column VARCHAR2(50);

My problem was solved!  Or, so I thought.  After trying a few times and getting error messages, I almost started to suspect a conspiracy — or at least a concerted effort was in place to confuse and befuddle…

Luckily, Coretek is staffed with experts on a wide variety of software and hardware platforms.  I reached out to our resident SQL guru, Avi Moskovitz, who informed me the “solution” I found referencing the  MODIFY statement WAS accurate – if used in an Oracle environment – but MS SQL 2008 does not support it. 

2 – Drastic, Dangerous, but Legitimate

One possible option is to create a new column and delete the old column; something you should not be in a hurry to do if you have data in the column as you need to think about how the data will be repopulated within the column (will it affect links, relationships, etc., or will it be truncated or corrupted?).  I have found that creating a new column in the SQL backend (with the correct parameters) and then going to the front end (if you happen to have something like an Access front-end) to copy the information from the old column and pasting into the new column will work; but beware of deleting a key or a linked field. 

3 – More Drastic, Less Desirable

Another, more drastic and less desirable option is to re-create the entire table in the SQL backend with the correct parameters.  This is a multi-step process that, depending on the size of the table, can take 5 to 30 minutes (or more, if there are hiccups along the way).  In doing this, you are effectively manually re-creating what SQL does when changing a data type for a field.  Not necessarily recommended, but I am keeping these steps provided by Avi in case I ever need them:

  1. Create a temporary table which will host your data (let’s call it MyTempTable).
  2. Copy the data from the original table (MyFirstTable) to MyTempTable, making sure that you set Identity_Insert “ON” so that it keeps the Key Field intact when the data gets copied in.
  3. Delete MyFirstTable. 
  4. Recreate the original table (a duplicate if you will of MyFirstTable…MySecondTable)
  5. Copy the data from the MyTempTable to the New MySecondTable making sure that you set Identity_Insert “ON” so that it keeps the Key Field intact when the data gets copied in.

4 – There’s a Right Way

But perhaps the best way of all, is to use a variant of the first thing mentioned above, correctly formatted for MS SQL 2008 with ALTER COLUMN instead of MODIFY, as follows:

 ALTER TABLE my_table ALTER COLUMN this_column NVARCHAR(50);

Execute this command into the query analyzer, and in an instant the problem is solved; the data type is changed (as in the graphic below)! 

SQL ALTER COLUMN Command - Successful!

SQL ALTER COLUMN Command – Successful!

Fortunately, the query analyzer will fail to execute if it detect data that does not fit the new type.  So what’s the lesson?  Internet searches are not a fool-proof way to explore scripting options; without the experience to understand the ramifications, the options can sometimes do as much harm as good…

 

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

2017-07-27T00:01:07+00:00 May 30th, 2012|Uncategorized|

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:tempexportmyexport-%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:tempexportmyexport-20120531.txt

Enjoy…

😎

(Updated 20120809 for OS version clarification)

Creating a “drop box” for Collecting Workstation Information…

2017-07-27T00:01:07+00:00 May 23rd, 2012|Uncategorized|

If you manage workstations in an enterprise, you know that administrators occasionally need to create a centralized repository where scripts and programs can write output/results.  Sometimes these scripts utilize a user credential, sometimes not; either way, users mustn’t see the contents.

To create such a hidden “drop box” type of folder (notice the lower-case “d”; I don’t mean to refer to a well-known trademark in any way) on a Windows server — where all users and/or computers in a domain may create folders and/or drop a files in that folder but never see what is in the folder(s) — you typically would create either a hidden folder on an existing share, or create a “hidden” share for the hidden folder.

To do so, create one of the following:

Option 1: Folder, on an existing share
If you intend to create a folder on an existing Windows share for the purpose of creating the “drop box”, do this:
a.) Create the folder (we chose “UserFileArchive” to avoid spaces for scripting)
b.) Right-click the folder, choose Properties, and the Security tab.
c.) Click Advanced, and the Change Permissions button.
d.) Un-check the Include Inheritable permissions box, and click the “Add” button at the prompt
e.) Remove any “Users” permissions, if found.
f.) Click the Add… button, and type in “Authenticated Users”, and click OK.
g1.) If the users must be able to create folders (as well as files) and drop files in them, set the following items:
  Apply onto: This folder, subfolder, and files
  Permissions: Create Files – Allow
  Permissions: Create Folders – Allow
g2.) If the users only need to drop files in the root folder, set the following items:
  Apply to: This folder only
  Permissions: Create Files – Allow
h.) Click OK, OK, OK, and OK.

Option 2: Shared Folder
If you intend to create a Shared Folder on a Windows server for the purpose of creating the “drop box”, do this:
a.) Create the folder (we chose “UserFileArchive” to avoid spaces for scripting)
b.) Right-click the folder, choose Properties, Sharing, and the Advanced Sharing button.
c.) Check the Share this folder box, name the share with a dollar-sign at the end (in our example, UserFileArchive$)
d.) Click the Permissions button, highlight/remove “Everyone”.
e.) Click the Add button, and type in “Authenticated Users”, and click OK.
f.) Set the permissions; typically, there’s nothing wrong with giving “Full Control”, but at least set “Change” and “Read”.
g.) Click OK, and click on the Security tab.
h.) Continue with step “c.” in Option 1 above.

After having created the above folder and settings, you may now copy files (or folders) into the hidden location using the “copy” command (or scripts), specifying the full destination path.  Of course, you can’t browse there to see it with a regular user permission to see the results, but that is as intended. 

If you wish, you can now create an additional permission for a user or group that may need to read the results (other than the Administrators), but you are well on your way to collecting system results across the network.

Go to it!

 

 

 

More DOS batch file fun…

2017-07-27T00:01:07+00:00 April 18th, 2012|Uncategorized|

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!

Load More Posts