01 November 2007

Free/Busy Error Outlook/Exchange

Some users complaint that after they received owner rights on a calendar (set with Outlook) they couldn't make new appointments. They received the following message "An error occurred when setting schedule permissions. Cannot open the free/busy information. You do not have sufficient permissions to perform this operation on this object. See the folder contact or your system administrator". One user didn’t have this problems. The problem exists in both Outlook 2003 and 2007.

I reproduced the problem by giving me the same rights as the complaining group of users. And I had exactly the same error. I tried starting Outlook with the /cleanfreebusy switch, but this wasn’t a solution.
The user without the problem had one difference. She was AD owner of the mailbox and the other users are owner set within Outlook of the mailbox and calendar. Added the owner rights of the mailbox to my account. Restarted Outlook and all problems are gone.

Other mailboxes don’t have this problem. The only thing we can think of is the “&“ character in the username and display name. We are going to correct this and will try again.
I will keep you posted!

17 October 2007

Exchange Message Tracking

Today, a customer had a strange problem. An end-user had send a message to 69 recipients with a small attachment (not important in this case). After a couple of minutes the user reported that she and a colleague received dozens of messages all send by the original sender.

She had the message only once in her send items. I checked the recipients in the message and I didn’t find any faults made by the user. The next step was checking Exchange Message Tracking. This reported that the actually has send the email. There was only one strange thing. The original message showed her Display Name and all the other messages showed her email address.

While we were searching for a solution the end user was called by multiple recipients complaining that they received the email 100+ times. So we decided to disable all outbound email. Because we are using SurfControl Email filter as a gateway I created a rule on this server for isolating all messages from that particular email address.

After I disabled all outbound email the flood of messages wouldn’t stop. The queue on the Exchange server didn’t contain any messages from the end user. The gateway’s queue also didn’t contained any messages. So I analyzed the headers of the isolated messages. The headers didn’t contain information about our servers sending the email. The server was only listed as the receiving end server. I asked a friend to take a look at the headers (thanks Jasper) because after a while I was losing all logic due to watching too long. Together we found the source of all evil: the server of one of the recipients. Called the organization and they disabled all outbound email until they will found a proper solution. After a while the flooding stopped.

The thing confused me the most was Exchange Message Tracking, because all the messages appeared in this logs just like the user has send the messages. The reason is pretty simple: if a message arrives at the server Exchange Message Tracking tracks this message in the database. If the email address of the sender is similar of to an email address from of an user, Exchange will record this message as a message send by the user ALSO in the situation that the email address is spoofed.
There’s only one simple solution. Messages send from within the network use the Display Name of the user. In my particular situation the email address was listed. So take a good look in this type of situations.

In my opinion this type of messages shouldn’t be listed in the Message Tracking Log only in a situation that the message is send by a server in his Exchange organization. Just a thing to keep in mind!

10 October 2007

Visionapp Remote Desktop

As an Administrator you probably uses the program Remote Desktops from Microsoft to access your servers. This works perfect, but has a big disadvantage. The problem is that you can’t sort the list with servers.

A new colleague showed me today an product which you can sort and acts just like Remote Desktops. It’s called Visionapp Remote Desktop. Version vRD 1.5 has also support for Vista.
You can now organize your servers in your own specific needs (geographic, alphabetical, etc, etc.)



Special Functions:
• Credential organizer. You can make groups of servers which uses the same credentials to login. You can direct the credentials to these groups so you don’t have to supply the credentials to each server individually. NOTE: Please don’t forget the security risks when using this option. The security risk is the same when using Remote Desktop, but the difference is the time saving option to distribute the credentials to a group of servers.
• Tabs with connected servers.
• Different icon when connected. Easily see to which servers you’re connected.
• Connect and disconnect groups of servers.
• Password protected backup file of configuration. Distribute your configuration easy and secure to colleagues.
• And much more…

There’s also another big advantage, because this program is freeware.

You can download it HERE at the site of Visionapp. NOTE: you must register first to download.

Active Directory Topology Diagrammer

Microsoft Technet sended today to there Dutch subscribers a newsletters. In this newsletter they always have a small section with downloadable products. Today they advised a program called “Active Directory Topology Diagrammer”.

The description of Microsoft about this program is: “The Microsoft Active Directory Topology Diagrammer reads an Active Directory configuration using ActiveX Data Objects (ADO), and then automatically generates a Visio diagram of your Active Directory and /or your Exchange 200x Server topology. The diagramms include domains, sites, servers, administrative groups, routing groups and connectors and can be changed manually in Visio if needed.”


Downloaded and installed it immediately. This is pure gold! It’s a three step procedure.
1. Fill in some information about a Global Catalog in your organization.
a. Check or uncheck some checkboxes for more or less information (optional).
2. Hit the discover button
3. After the discovery, Hit the Draw button and sit back and relax while your Active Directory and Exchange organisation will be drawn in Visio.

Download it at Here at Microsoft.

Reinstallation of a SBS2003 with Transition Packs

For a customer we transformed a Small Business Server 2003 server with Transition Packs to a Windows Server 2003 Standard. After a successful migration of 2 networks the server loses his role as a DC and his function in the new network. We wanted to use this server in a complete different role and network.

But there’s the question what to do with the OS of this server. The server contains a lot of garbage and leftovers of the original Small Business Server installation even after a cleanup. Continuing with this server in this configuration would cause a lot of problems in the future. The Eventviewer contained a lot of errors caused by the Small Business configuration. Reinstallation was the only good option.

There’s only one problem. What is the correct reinstallation path in this situation?
1. Installing Small Business Server 2003
2. Applying Transition Packs
3. Using the transformed Windows Server 2003.

In this situation we would get the same problems before we started. Garbage and leftovers from the SBS2003 installation. Google wouldn’t help in this situation (where is Google if you really need it ). Eventually I called the License Helpdesk of Microsoft. They couldn’t helped me and advised me to call the Technical Support desk of Microsoft. Rather strange because in my opinion this is just a license issue: "Can and may I use the product key from the Transition Packs with a retail Media Kit of Microsoft Windows Server 2003?".

The answer is YES. I called the Technical Support desk of Microsoft and they haven’t received this question earlier, but his answer was that this was purely a license issue. If I installed this configuration and I get an audit by Microsoft or other organisation this won’t be a problem if I got the original Small Business Server License and the Transition Packs license present.

The only problem is of this really works. Can I use the serial number as printed on the Transition Packs case when installing Windows Server 2003 standard. The answer is also YES. Today I started the reinstallation of the system. Used a Retail Windows Server 2003 CD and the product code (serial number) of the Transition Pack and this works flawless.

23 May 2007

The hard Part of WinForm (Visual Studio)

Logic is one part of programming, but I now realize that the hard part when creating an application is the graphic interface. I have recreated my GUI for the third time. Finally I have a design which I think is simple and easy to use. It just looks like a normal program.. ;-)

First Design:
My first steps in the design of the GUI. Looks nice and simple, but I need some more buttons and options. The style is too basic for the program.


This looks bad, very bad:
This is an example no to do it. Every button you think you need on one window. It works, but not user friendly.


Final Design, at least for now:
With a menu bar it looks more like every other program. I can hide some user controls, but most of all: it’s more user friendly. It can also show some information to the user.


I will add some extra status information, but it won’t be a fancy carnival.

12 May 2007

Profile Cleanup VB.NET style

As told previously, my next plan was to build the profile cleanup with VB.NET. This will result in an application useable by almost everyone. I'm making great progress in the last days. I'm a complete Visual Basic or VB.NET newby so it will take longer to complete. I have to change a lot of code, but it is a nice challenge.

I only have to integrate the external tools like takeown.exe and xcacls.exe and make some control checks. I keep you updated!

06 April 2007

Profile Cleanup Script PART TWO

I have changed the script for better workflow. In the old script you have to wait thru the whole script. This has been changed. The script now checks first which folders doesn't correspond with a user in Active Directory. It asks you first if you want to reset the permissions and delete the folder. After all folders have passed it starts with the actual resetting and removing of the selected folders.

This will save you a lot of time if you have a lot of old user profile folders, because you don't have to wait during resetting and deleting. The following update will contain a logging function. You will be asked if you want to run this script in logging mode and it will save all of the old user profiles to a text-file.

You can download the script here

 

'============================================================================
'
VBScript Source File
'
NAME: Rechten Home-Directory
'
AUTHOR: Ruudvdh (WASTEIL)
'
WEBSITE: http://wasteil.blogspot.com
'
DATE : 05-04-2007
'
COMMENT: This script checkes in the profile folder for foldernames
'
which are not corresponding with a user in Active Directory. You will be
'
asked te reset the rights on the folder who doesn't have a matching
'
Username.
'
'
============================================================================

' DECLARING VARIABLES
Option Explicit
DIM answer, commando, colProcess, collection
DIM counter1, counter2, counter3
DIM Folder, FSO
DIM intReturnValue, iReturn
DIM objCommand, objConnection, objFSO
DIM objRecordSet, objRootDSE, objShell
DIM objWMIService, objProcess
DIM processrun, rootFolder
DIM strObjectName, strComputer, strFold
DIM strRootSearch, SubFolders

' INSTANTIATING AN OBJECT
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objShell = wscript.createObject("wscript.shell")
SET objRootDSE = GetObject("LDAP://RootDSE")
SET collection = CreateObject("Scripting.Dictionary")

' ASSIGNING VALUES TO CONSTANTS
CONST strObjectType = "user"
CONST strFile1 = "C:\Windows\system32\takeown.exe"
CONST strFile2 = "C:\Program Files\Support Tools\xcacls.exe"

' ASSIGNING VALUES TO VARIABLES
strFold = Lcase(Inputbox(Ucase("Enter path profile folder") &VbCr &VbCr _
&"Use the following style:" &VbCr _
&"D:\Profiles\","Profile Folder","D:\Profiles\"))
DIM process(2)
process(
1) = "takeown.exe"
process(
2) = "xcacls.exe"

strRootSearch
= objRootDSE.Get("RootDomainNamingContext")
strComputer
= "."
counter2
= 1
counter3
= 0

'================================SUBS=========================================
'
SUB-procedure for checking folder name with user in Active Directory
SUB ADcheck()
SET objConnection = CreateObject("ADODB.Connection")
objConnection.Open
"Provider=ADsDSOObject;"
SET objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection
= objConnection
objCommand.CommandText
= _
"<LDAP://" & strRootSearch & ">;(&(objectCategory=" & strObjectType & ")" & _
"(samAccountName=" & strObjectName & "));samAccountName,distinguishedName;subtree"

SET objRecordSet = objCommand.Execute
IF objRecordset.RecordCount = 0 THEN
answer
= MsgBox("Would you reset rights and delete folder "_
&Ucase(strObjectName),4,"Reset rights and Delete Folder")
IF answer = 6 THEN
collection.Add counter2,strObjectName
counter2
= counter2 + 1
END IF
intReturnValue
=0
ELSE
objRecordSet.MoveFirst
intReturnValue
=1
END IF
objConnection.Close
END SUB

' SUB-procedure for checking running process
SUB processCHK()
DO
processrun
= 0
SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
SET colProcess = objWMIService.ExecQuery ("Select * from Win32_Process")
FOR Each objProcess in colProcess
IF objProcess.Name = process(counter1) THEN
processrun
= processrun + 1
END IF
NEXT
IF processrun > 0 THEN
wscript.sleep(
5000)
END IF

SET objWMIService = nothing
SET colProcess = nothing
Loop Until processrun = 0
END SUB

' SUB-procedure for reading folder names
SUB strControl()
SET rootFolder = objFSO.GetFolder(strFold)
SET SubFolders = rootFolder.SubFolders
FOR Each Folder IN SubFolders
strObjectName
= replace(Lcase(Folder),strFold,"")
CALL ADcheck()
NEXT
SET rootFolder = NOTHING
SET SubFolders = NOTHING
END SUB

SUB ResetRights()
counter3
= counter3 + 1
commando
= "takeown /F " &strFold &collection.Item(counter2) &" /R /A /D Y"
iReturn
= objShell.Run(commando)
counter1
= 1
CALL processCHK()

commando
= "xcacls " &strFold &collection.Item(counter2) &" /g ""Domain Admins"":F /T /C /Y"
iReturn
= objShell.Run(commando)
counter1
= 2
CALL processCHK()
objFSO.DeleteFolder strFold
&collection.Item(counter2),TRUE
END SUB

'=============================END=OF=SUBS=====================================
'
'
================================CODE=========================================

IF objFSO.FolderExists(strFold) THEN
IF objFSO.FileExists(strFile2) THEN
IF objFSO.FileExists(strFile1) THEN
CALL strControl()
FOR counter2 = 1 to collection.Count
CALL ResetRights()
NEXT
answer
= MsgBox(counter3 &" Folders reset and deleted",0,"Finished")
ELSE
answer
= MsgBox(strFile1 &" not found." &VbCr _
&"Press [YES] to open website to to download",4,strFile1 &" not found!")
IF answer = 6 THEN
iReturn
= objShell.Run("http://www.petri.co.il/download_free_reskit_tools.htm")
END IF
END IF
ELSE
answer
= MsgBox(strFile2 &" not found." &VbCr _
&"Press [YES] to open website to to download",4,strFile2 &" not found!")
IF answer = 6 THEN
iReturn
= objShell.Run("http://support.microsoft.com/kb/892777")
END IF
END IF
ELSE
wscript.Echo
"Folder: " &Ucase(strFold) &" doesn't exist." &VbCr _
&"Verify the location and try again."
END IF

SET objCommand = NOTHING
SET objConnection = NOTHING
SET objFSO = NOTHING
SET objRecordSet = NOTHING
SET objShell = NOTHING
SET rootFolder = NOTHING
SET SubFolders = NOTHING

'=============================END=OF=CODE=====================================
wscript.quit

04 April 2007

Reset Permissions Home Folder

 

I'm busy with a migration of two domains. One Domain will eventually be removed. This domain residence all of the user profiles and home folders. All the Home folders still uses the permissions of the old domain. Works perfectly at the moment, but when that domain will be removed it is going to be a problem.

That's why I'm going to copy the home and profile folders from a server in the old domain to a new server in the new domain. I Only have to change the permissions on the home folders to match to the "new" users. You can do this manually or use xcacls, but you have to do this for every folder individually.

I have written a script that changes the permissions on all of the subfolders in a specified folder automatically. It uses the foldername (that must match with a username in Active Directory) as a username to give permissions. It also gives the Domain Administrators group access. You can change this to your needs.

You still need XCACLS. This is part of the Windows 2003 Support tools. You can download them here. NOTE: It has to be run directly on the server or used with a network mapped drive. UNC-path won't work.

Download script here.

 

'============================================================================
'
VBScript Source File
'
NAME: Permissions Home Folder
'
AUTHOR: Ruudvdh (WASTEIL)
'
WEBSITE : http://wasteil.blogspot.com
'
DATE : 19-3-2007
'
COMMENT: This script changes the permissions of all the subfolders in the
'
specified folders. It uses the folder name and matches this with a username
'
in Active Directory. Therefore the foldername must be equal to the username.
'
'
Permissions (See CONST UsrPerm1 & UsrPerm2:
'
R = Read
'
C = Change (write)
'
F = Full control
'
P = Change Permissions (Special access)
'
O = Take Ownership (Special access)
'
X = EXecute (Special access)
'
E = REad (Special access)
'
W = Write (Special access)
'
D = Delete (Special access)
'
'
!!!NEEDED PROGRAMS!!!
'
XCACLS.EXE
'
This program is part of the Support Tools
'
DOWNLOAD:
'
http://support.microsoft.com/kb/892777
'
'
============================================================================

' DECLARING VARIABLES
Option Explicit
DIM Commando, Counter, Domain
DIM Folder, iReturn, objFSO
DIM objShell, objSysInfo, rootFolder
DIM strFolder, strUser, SubFolders

' INSTANTIATING AN OBJECT PART1
SET objSysInfo = CreateObject("ADSystemInfo")
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objShell = wscript.createObject("wscript.shell")

' ASSIGNING VALUES TO VARIABLES
strFolder = Lcase(Inputbox(Ucase("Enter path Home folder") &VbCr &VbCr _
&"Use the following syntax:" &VbCr _
&"D:\Users\","Home-Folder","D:\Users\"))
Domain
= objSysInfo.ForestDNSName & "\"

' INSTANTIATING AN OBJECT PART2
SET rootFolder = objFSO.GetFolder(strFolder)
SET SubFolders = rootFolder.SubFolders

' ASSIGNING VALUES TO CONSTANTS
'
INFO: You can find the possible permissions in the comment
CONST Usr1 = "Domain Admins"
CONST UsrPerm1 = "F"
CONST UsrPerm2 = "RWC"

'================================CODE=========================================

IF objFSO.FolderExists(strFolder) THEN
FOR Each Folder In SubFolders
strUser
= replace(Lcase(Folder),strFolder,"")
commando
= "xcacls " &Folder &" /g ""Domain Admins"":" &UsrPerm1 _
&" """ &Domain &strUser &""":" &UsrPerm2 &" /T /C /Y"
iReturn
= objShell.Run(commando)
Counter
= Counter + 1
' This sleep is specially done to not overload the system with
' xcacls screens.
wscript.sleep 1500
NEXT
wscript.echo
"Finished!" &VBCR &Counter &" folders are reset."
ELSE
wscript.Echo
"Folder: " &Ucase(strFolder) &" doesn't exist." &VbCr _
&"Verify the location and try again."
END IF

SET objSysInfo = NOTHING
SET objFSO = NOTHING
SET objShell = NOTHING
SET rootFolder = NOTHING
SET SubFolders = NOTHING
'=============================END=OF=CODE=====================================
wscript.quit

02 April 2007

Profile Cleanup Script

In every organization users come and users go. Users are deleted, mailboxes are cleaned up, but most of the times the profile folder isn't cleaned up. After a couple of time there are a dozen of unused profiles located in the profile share. You can do this all by hand, but that's not the reason why you're working in IT. That's the reason I wrote this script.


This script automatically take ownership, reset the rights and deletes the folder. It only asks if you're sure to do all this actions.


NOTE: It has to be run directly on the server or used with a network mapped drive. UNC-path won't work.
This script is still in development. Updates will follow! The script works perfectly, but needs some finetuning for further automatization.


You can download the script here


 


'============================================================================
'
VBScript Source File
'
NAME: Rechten Home-Directory
'
AUTHOR: Ruudvdh (WASTEIL)
'
WEBSITE: http://wasteil.blogspot.com
'
DATE : 29-03-2007
'
COMMENT: This script checkes in the profile folder for foldernames
'
which are not corresponding with a user in Active Directory. You will be
'
asked te reset the rights on the folder who doesn't have a matching
'
Username.
'
'
!!!NEEDED PROGRAMS!!!
'
XCACLS.EXE
'
This program is part of the Support Tools
'
DOWNLOAD:
'
http://support.microsoft.com/kb/892777
'
'
TAKEOWN.EXE -->
'
This program is part of the Windows 2000 Resource Kit tools
'
Windows Server 2003 already has this file in the C:\WINDOWS\SYSTEM32 folder
'
DOWNLOAD:
'
http://www.petri.co.il/download_free_reskit_tools.htm
'
Extract the takeown.exe in the C:\WINDOWS\SYSTEM32\ folder.
'

'
============================================================================

' DECLARING VARIABLES
Option Explicit
DIM answer, commando, colProcess
DIM counter1, counter2, counter3
DIM Folder, FSO
DIM intReturnValue, iReturn
DIM objCommand, objConnection, objFSO
DIM objRecordSet, objRootDSE, objShell
DIM objWMIService, objProcess, objTextFile
DIM processrun, result, rootFolder
DIM strFile, strFolder, strObjectName
DIM strComputer, strRootSearch, SubFolders

' INSTANTIATING AN OBJECT
SET objFSO = CreateObject("Scripting.FileSystemObject")
SET objShell = wscript.createObject("wscript.shell")
SET objRootDSE = GetObject("LDAP://RootDSE")

' ASSIGNING VALUES TO CONSTANTS
CONST strObjectType = "user"
CONST ForAppending = 8
CONST ForReading = 1
CONST ForWriting = 2

' ASSIGNING VALUES TO VARIABLES
DIM strFold(1)
strFold(
1) = Lcase(Inputbox(Ucase("Enter path profile folder") &VbCr &VbCr _
&"Use the following style:" &VbCr _
&"D:\Profiles\","Profile Folder","D:\Profiles\"))
DIM process(2)
process(
1) = "takeown.exe"
process(
2) = "xcacls.exe"
DIM strFile2(2)
strFile2(
1) = "C:\Windows\system32\takeown.exe"
strFile2(
2) = "C:\Program Files\Support Tools\xcacls.exe"
strRootSearch
= objRootDSE.Get("RootDomainNamingContext")
strComputer
= "."

'================================SUBS=========================================
'
SUB-procedure for checking folder name with user in Active Directory
SUB ADcheck()
SET objConnection = CreateObject("ADODB.Connection")
objConnection.Open
"Provider=ADsDSOObject;"
SET objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection
= objConnection
objCommand.CommandText
= _
"<LDAP://" & strRootSearch & ">;(&(objectCategory=" & strObjectType & ")" & _
"(samAccountName=" & strObjectName & "));samAccountName,distinguishedName;subtree"

SET objRecordSet = objCommand.Execute
SET objTextFile = objFSO.OpenTextFile (strFolder & strFile, ForAppending, True)

IF objRecordset.RecordCount = 0 THEN
IF result = 2 THEN
CALL ResetRights()
END IF
objTextFile.WriteLine(strObjectName)
intReturnValue
=0
ELSE
objRecordSet.MoveFirst
intReturnValue
=1
END IF
objTextFile.Close
objConnection.Close
END SUB

' SUB-procedure for checking running process
SUB processCHK()
DO
processrun
= 0
SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
SET colProcess = objWMIService.ExecQuery ("Select * from Win32_Process")

FOR EACH objProcess in colProcess
IF objProcess.Name = process(counter2) THEN
processrun
= processrun + 1
END IF
NEXT

IF processrun > 0 THEN
wscript.sleep(
5000)
END IF

SET objWMIService = nothing
SET colProcess = nothing
Loop Until processrun = 0
END SUB

' SUB-procedure for checking if al external programs are available on the system
SUB ProgramExist()
result
= 0
FOR counter3 = 1 to 2
IF objFSO.FileExists(strFile2(counter3)) THEN
result
= result + 1
END IF
NEXT
END SUB

' SUB-procedure for reading folder names
SUB strControl()
SET rootFolder = objFSO.GetFolder(strFolder)
SET SubFolders = rootFolder.SubFolders
FOR Each Folder IN SubFolders
strObjectName
= replace(Lcase(Folder),strFolder,"")
CALL ADcheck()
NEXT
SET rootFolder = NOTHING
SET SubFolders = NOTHING
END SUB

SUB ResetRights()
answer
= MsgBox("Would you reset rights and delete folder " &strObjectName,4,"Reset rights and Delete Folder")
IF answer = 6 THEN
commando
= "takeown /F " &Folder &" /R /A /D Y"
iReturn
= objShell.Run(commando)
counter2
= 1
CALL processCHK()

commando
= "xcacls " &Folder &" /g ""Domain Admins"":F /T /C /Y"
iReturn
= objShell.Run(commando)
counter2
= 2
CALL processCHK()
objFSO.DeleteFolder Folder,
TRUE
END IF
END SUB

'=============================END=OF=SUBS=====================================
'
'
================================CODE=========================================
CALL ProgramExist()
FOR counter1 = 1 To 1
strFolder
= strFold(counter1)
IF objFSO.FolderExists(strFolder) THEN
strFile
= Replace(Replace(strFold(counter1),Left(strFold(counter1),3),""),"\","") &"-folders.txt"
SET objTextFile = objFSO.OpenTextFile (strFolder & strFile, ForWriting, True)
objTextFile.Close
CALL strControl()
ELSE
wscript.Echo
"Folder: " &Ucase(strFolder) &" doesn't exist." &VbCr _
&"Verify the location and try again."
END IF
NEXT

wscript.Echo
"FINISHED!"
SET objCommand = NOTHING
SET objConnection = NOTHING
SET objFSO = NOTHING
SET objRecordSet = NOTHING
SET objShell = NOTHING
SET rootFolder = NOTHING
SET SubFolders = NOTHING

'=============================END=OF=CODE=====================================
wscript.quit