VBScript: Monitor a folder for new files


The Following link from MS Technet Script Center was exactly what I wanted.

Link to Hey, Scripting Guy! How Can I Automatically Run a Script Any Time a File is Added to a Folder?

Scripting guys at Technet are doing a great job on scripts and examples. I usually I look in script center before I try searching all over the Internet. I met Peter Costantini and Dean Tsaltas on a NT user group occation. Awesome guys.

Advertisements

Exchange ActiveSync Gripes


Notes and ActiveSync – Why?

I came pretty disappointed when I realized Exchange ActiveSync is not supported with (Outlook) Notes sync. So,I looked Exchange 2007 Active Sync and no where mentioned Notes sync is on the horizon. So, I take it Notes sync will never be included in ActiveSync now or in future.

According to this link, Exchange 2007 ActiveSync can sync voice messages and fax attachments from mailbox, but NOT "Notes".

I don’t know what complication MS has with Notes synching using Exchange ActiveSync. Otherguys on the same block (BlackBerry, Good, iAnywhere,Seven, etc.,) have no problem synching Notes.

PocketPC/Smartphone Backup and ActiveSync – Missing feature

You know what else would be really cool feature…over the air Backup and Restore. I know iAnywhere has it with OneBridge software. It’s a full backup (including memory card) to the server wirelessly. If it saves you at least one time  in a critical situation, it’s worth it. May be, some third party guys should work on extending Exchange ActiveSync if it is possible. (On this paragraph,I have to mention that WM5 has no in-built backup feature and I don’t see it in ActiveSync 4.5 Beta 2)

ISA 2004: OWA, RPC/HTTP, OMA, ActiveSync on same Listener (works)


Here is one conflicting information goes around the Internet. ISA 2004 cannot publish all four Exchange features (OWA, OMA, ActiveSync and RPC/HTTP) in one single listener. I have searched the Microsoft site (technet) and ISAServer.org.  Here is the links for related ISA 2004 and Exchange publishing.

http://www.microsoft.com/technet/isa/2004/plan/outlook_web_access_publishing_ee.mspx

http://www.microsoft.com/technet/isa/2004/library/default.mspx

http://www.isaserver.org/articles/2004pubowartm.html

http://www.isaserver.org/tutorials/Redirecting-OWA-Users-Part1.html

http://support.microsoft.com/kb/839357/en-us

http://www.isaserver.org/articles/2004unihomedowapart1.html

 

None of the above links describes how to run all 4 features published in one single listener on same External network card. The problem I am talking about is this….

-OWA needs to be setup with Forms Based Athentication on ISA 2004 server (more secure design)

– Rest of the items (OMA, ActiveSync and RPC/HTTP) requires Basic Authentication (over SSL). Outlook 2003 or mobile devices will not handle the Form Based Authentication, so it needs to be on Basic authentication.

So, all the Microsoft and other documents leads to create two different listeners (one with FBA and one with Basic authentication). Two listener cannot listen on same IP address and same port (443). Two different listener means two different IP addresses.  And it also means two different domain names (owa.xxx.com and rpc.xxx.com). It complicates more like we have to buy two different digital certifications from provides (VeriSign) unless you choose to run Certificate Services in home.

Then, I found this article and may shed light for the solution: http://www.isaserver.org/tutorials/2004pubowamobile.html.

After I reading the above link, I realized this is not going to work for me. We bought a SSL certificate from legitimate provider and we don’t run certificate services at my company and we don’t plan to setup. For some small business and other companies, it may do some magic.

I was frustrated and about to gave up. I fiddled around and found something in the middle. All four features (OWA, OMA,ActiveSync and RPC/HTTP) are working on a single listener. Here is my setup. See the drawing and I will explain it below.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Here is the steps:

– Create a Listener called FBA_443_Listener with above settings in the drawing. Note this listener has only FBA selected. Don’t forget to set the default domain (your AD domain). If the users are from different domain in the forest, they have to type "domainusername" format.

– Create a Firewall Rule with Mail Server Publishing Wizard. Name it "OWA Publishing Rule". Select only OWA during the wizard. Setup the rule with above settings as it is in the drawing. When asked, select FBA_443_Listener. You need to enter path after finish creating the rule.

– Create a second firewall rule with Web Server Publishing Wizard and name it "RPC/HTTP,OMA and ActiveSync Publishing Rule". (Note the bold letters, this has to be created using web server publishing wizard and NOT using mail server publishing wizard). When asked, provide the path name as /rpc/* with your OWA domain name (mail.xxx.com). Make sure the settings are correct with above drawing. You need to add all the paths manually after creating the rule.

Voila! It worked. I am no geek on ISA server side, but here the explanation. The magic here is you create the rule for RPC, OMA and ActiveSync using WEB SERVER PUBLISHING WIZARD. I still don’t get it that how Outlook and my Mobile handles Form based authentication with above setup. But some how it handles it.

One possibility is Microsoft made Outlook and WM5 to manage the FBA through the latest patches. OR ISA 2004 with SP2 handles the NON Browser calls with Basic Authentication. So, don’t forget to patch your servers and clients.

Here is the result:

– Outlook Web Access link is provided with FBA logon page

– OMA provided with Basic Authentication page

– ActiveSync works and NO errors

– RPC/HTTP is provided with logon window in Outlook 2003 and it works without errors

This above setup works and I can do all four Exchange features beautifully.  With all that above, I am running ISA 2004 in single network configuration. The listener is set to listen on local network.

Hope it helps someone desperately looking for the information.

Convert UTC to local time and vice versa using VBScript


 

Today, I was stumbled upon UTC time conversions. I needed to convert UTC date/time to local date/time and vice versa. I was hunting this information everywhere with no luck.

I didn’t get the straight answer anywhere. So, I gathered all the info and created two VBScript based Functions. Hope it helps someone.

Here is the formula for converting time:

Local time to UTC: local time + (Bias / 1440 ) = UTC 
UTC to Local Time: UTC – (Bias/1440) = Local Time

Bias is available on the registry which tell what Time Zone is on the local computer. You can check the registry location at HKEY_LOCAL_MACHINESystemCurrentControlSetControlTimeZoneInformationActiveTimeBias

The ActiveTimeBias is the value of Bias/1400.

So, it came down to Adding the Bias to Local Time gives you the UTC time and Subtracting the Bias from UTC gives the local time.

Now the VBScript implementation of converting the times back and fourth.

‘*************************************************************************
‘ Name: ConvertToUTCTime ( sTime as Date )
‘ Parameters: Takes the Local Time. eg., 11/07/2006 10:00:00 AM
‘ Returns the converted UTC Time as 2006-11-07T18:00:000Z

‘ Written by : Anand Venkatachalapathy
‘*************************************************************************
Function ConvertToUTCTime(sTime)

          Dim od, ad, oShell, atb, offsetMin
          Dim sHour, sMinute, sMonth, sDay

od = sTime
‘if you passed sTime as sting, comment the above line and
‘uncomment the below line.
‘od = CDate(sTime)

‘Create Shell object to read registry
Set oShell = CreateObject("WScript.Shell")

atb = "HKEY_LOCAL_MACHINESystemCurrentControlSet" & _
"ControlTimeZoneInformationActiveTimeBias"
offsetMin = oShell.RegRead(atb) ‘Reading the registry

‘Convert the local time to UTC time
ad = dateadd("n", offsetMin, od)

‘ If Month is single digit value, add zero
sMonth = Month(CDate(ad))
If Len(sMonth) = 1 Then
            sMonth = "0" & sMonth
End If

‘If Day is single digit, add zero
sDay = Day(CDate(ad))
If Len(sDay) = 1 Then
          sDay = "0" & sDay
End If

‘if Hour is single digit, add zero
sHour = Hour(CDate(ad))
If Len(sHour) = 1 Then
          sHour = "0" & sHour
End If

‘if Minute is single digit, add zero
sMinute = Minute(CDate(ad))
If Len(sMinute) = 1 Then
         sMinute = "0" & sMinute
End If

‘Assign the reutrn value in UTC format as 2006-11-07T18:00:000Z
ConvertToUTCTime = Year(CDate(ad)) & "-" & _
sMonth & "-" & _
sDay & "T" & _
sHour & ":" & _
sMinute & ":00Z"

End Function
‘ End of Function ConvertToUTCTime

 

‘*************************************************************************
‘ Name: ConvertToLocalTime ( sTime as Date )
‘ Parameters: Takes the UTC Time as 2006-11-07T18:00:000Z
‘ Returns the converted Local Time. eg., 11/07/2006 10:00:00 AM

‘ Written by : Anand Venkatachalapathy
‘*************************************************************************
Function ConvertToLocalTime(sTime)

Dim od, ad, oShell, atb, offsetMin
Dim sHour, sMinute, sMonth, sDay
Dim ResultDate

‘Convert the UTC time 2006-11-07T18:00:000Z to
‘a normal date format 11/07/2006 10:00:00
‘Note the converted date would be 24 hr format
od = CDate( _
                     Mid(sTime,9,2) & "-" & _
                     Mid(STime,6,2) & "-" & _
                     Mid(STime,1,4) & " " & _
                     Mid(STime,12,8) _
                )

‘Create Shell object to read registry
Set oShell = CreateObject("WScript.Shell")

atb = "HKEY_LOCAL_MACHINESystemCurrentControlSet" & _
"ControlTimeZoneInformationActiveTimeBias"
offsetMin = oShell.RegRead(atb) ‘Reading the registry

‘Make the Bias as negative value. This step is required,
‘because VBScript offers only DateAdd function. I wish,
‘there is DateSubtract function in VBScript.
offsetMin = -(offsetMin)

‘Convert the UTC time to Local Time,
‘Note the OffsetMin is negative value
ad = dateadd("n", offsetMin, od)

‘ If Month is single digit value, add zero
sMonth = Month(CDate(ad))
If Len(sMonth) = 1 Then
                sMonth = "0" & sMonth
End If

‘ If Day is single digit value, add zero
sDay = Day(CDate(ad))
If Len(sDay) = 1 Then
              sDay = "0" & sDay
End If

‘ If Hour is single digit value, add zero
sHour = Hour(CDate(ad))
If Len(sHour) = 1 Then
              sHour = "0" & sHour
End If

‘ If Minute is single digit value, add zero
sMinute = Minute(CDate(ad))
If Len(sMinute) = 1 Then
            sMinute = "0" & sMinute
End If

‘ Gather up all fields and convert to a Date format
ResultDate = cDate(sDay & "-" & sMonth & "-" & Year(CDate(ad)) & " " & sHour & ":" & sMinute & ":00")

‘In the above step, ResultDate is in 24 hour format.
‘So convert into 12 hr format and assign the return value
ConvertToLocalTime = FormatDateTime(ResultDate,vbShortDate) & " " & FormatDateTime(ResultDate,vbLongTime)

End Function
‘End of ConvertToLocalTime Function

Windows 2003 Cluster monitor script for Exchange 2003 server


 

Hello, Here is my another script I made it to monitor my company’s Exchange 2003 cluster. If you run Exchange 2003 server on Windows 2003 cluster, this might help you.

Here are the needs for this script,

– Exchange cluster group might be failover to another node for some reason. I want to know why it did failover and when. Most importantly, How much time it takes to failover.

– For Better practice, I set "affect the group" settings only to very important core resources. If all other resources fails, it will not affect the group and stays failed. If that happens for any reason. I want to know when it happens.

– Run this script from a standalone server. Do not run this on the cluster node(s) itself. It beats the reason for this script. It uses WMI, so it can run from any Windows 2000, Windows 2003 or XP machine.

It’s basic VBScript and I found the help from MSDN website. Anybody can reuse this script by providing the Exchange cluster server name, an SMTP server name and Administrators who needs to receive email alerts.

NOTE: You need to have an SMTP server other than the Exchange server itself. If the Exchange is down on the cluster, you need to send alert mails via different SMTP server.

Questions, leave me reply. OK Let’s get to the script.

 

‘===============================================================
‘ Name: ClusterProbe.vbs
‘ Purpose: Check each Cluster member found for Exchange server,
‘ and Check all properties on the ExchangeClusterResource
‘ objects. If the state is other than 2, send emails
‘ to administrators
‘Written by: Anand Venkatachalapathy
‘Written Date: Sep 9 2006
‘===============================================================

Dim strAdministrators ‘Who supposed to receive alerts

StrAdministrators = "Adminname@company.com;pageremail@pager.com"

Dim sSMTpServerName ‘* sSMTPServerName – SMTP Server Name

‘* SMTP server – This server should not be your Exchange server.
‘* If your Exchange cluster is down, you need to send alerts. So, assign it to
‘* a different Server
sSMTPServerName = "YourSMTPServerName"

Check_Cluster_Resources "YourExchangeClusterName"

‘===============================================================
‘ Name: Check_Cluster_Resources
‘ Purpose: Check each Cluster member found for Exchange server,
‘ and Check all properties on the ExchangeClusterResource
‘ objects. If the state is other than 2, send emails
‘ to administrators
‘ Input: strComputerName [string] the computer to access
‘ Output: If the state is other than 2, calls Alert_Admins sub
‘ to send emails
‘===============================================================
Public Sub Check_Cluster_Resources ( strComputerName )

Const cWMINameSpace = "root/cimv2/applications/exchange"
Const cWMIInstance = "ExchangeClusterResource"
Const ForReading = 1, ForWriting = 2, ForAppending = 8

Dim strWinMgmts ‘ Connection string for WMI
Dim objWMIExchange ‘ Exchange Namespace WMI object
Dim listClusterResources ‘ ExchangeClusterResource collection
Dim objExchangeConnector ‘ A single ExchangeClusterResource WMI object
Dim strResourceName
Dim strVirtualMachine
Dim strNodeName
Dim numResourceState, strStateDescription
Dim strResourceType
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("ClusterProbe.log", ForAppending, True)
f.WriteLine vbCRLF & "————————————————————–"
f.WriteLine Now & "- Checking cluster resources for " & strComputerName

‘ Create the object string, indicating WMI (winmgmts), using the
‘ current user credentials (impersonationLevel=impersonate),
‘ on the computer passed to the function in strComputerName, and
‘ using the CIM namespace for the Exchange provider.
strWinMgmts = "winmgmts:{impersonationLevel=impersonate}!//" & strComputerName & "/" & cWMINameSpace


‘ Get an object using the string you just created.
Set objWMIExchange = GetObject(strWinMgmts)


‘ The Resources that currently exist appear as a list of
‘ ExchangeClusterResource instances in the Exchange namespace.
Set listClusterResources = objWMIExchange.InstancesOf(cWMIInstance)


‘ Were any ExchangeClusterResource Instances returned?
if (listClusterResources.count > 0) then
‘ If yes, do the following:
‘ Iterate through the list of ExchangeClusterResource objects.
For each objExchangeConnector in listClusterResources
‘===============================================================
‘Following Values are taken from MSDN EXchange/Cluster website
‘Cluster Resource State descriptions:
‘ClusterResourceStateUnknown = -1,
‘ClusterResourceInherited = 0,
‘ClusterResourceInitializing = 1,
‘ClusterResourceOnline = 2,
‘ClusterResourceOffline = 3,
‘ClusterResourceFailed = 4,
‘ClusterResourcePending = 128,
‘ClusterResourceOnlinePending = 129,
‘ClusterResourceOfflinePending = 130
‘===============================================================
numResourceState = objExchangeConnector.State
strResourceName = objExchangeConnector.Name
strVirtualMachine = objExchangeConnector.VirtualMachine
strNodeName = objExchangeConnector.Owner
strResourceType = objExchangeConnector.Type
If numResourceState <> 2 Then
Select Case numResourceState
Case -1
strStateDescription = "Unknown"
Case 0
strStateDescription = "Inherited"
Case 1
strStateDescription = "Initializing"
Case 2
strStateDescription = "Online"
Case 3
strStateDescription = "Offline"
Case 4
strStateDescription = "Failed"
Case 128
strStateDescription = "Pending"
Case 129
strStateDescription = "OnlinePending"
Case 130
strStateDescription = "OfflinePending"
End Select
f.WriteLine strResourceName & " is NOT online at " & strNodeName
f.WriteLine "Alerting Administrators…."
strTo = strAdministrators
strSub = "<Exchange Cluster> " & strStateDescription & ": " & strResourceName
strBody = strResourceName & "(" & strVirtualMachine & ") is hosted at " & strNodeName & vbCRLF
strBody = strBody & strResourceName & "’state is changed to " & strStateDescription & vbCRLF
strBody = strBody & strResourceName & "’s type is " & strResourceType & vbCRLF & vbCRLF
Alert_Admins strTo,strSub,strBody
f.WriteLine "Alert sent to " & strAdministrators
Else
f.WriteLine strResourceName & " is ONLINE at " & strNodeName
End If

‘ Move to the next ExchangeClusterResource.
Next
else
‘ If no ExchangeClusterResource instances were returned,
‘ display that.
f.WriteLine "No ExchangeClusterResource instances were returned."
strTo = strAdministrators
strSub = "<Exchange Cluster> " & strComputerName & " is not responding"
strBody = strComputerName & " is not available on the network"
Alert_Admins strTo,strSub,strBody
f.WriteLine "Alert sent to " & strAdministrators
end if
f.close
end Sub

‘===============================================================
‘ Name: Alert_Admins
‘ Purpose: Send email using smtp server.
‘ Input: strTo – Who to send to, strSub – Subject of the message
‘ strBody – Body of the message
‘ Output: Sends the emails to the strTO recipients
‘===============================================================
Sub Alert_Admins( strTo,strSub,strBody)
‘* iMsg – holds CDO.Message object
‘* Flds – Enumeration for CDO SMTP object properties
‘* iConf – holds CDO.Configuration
Dim iMsg, Flds, iConf

‘* Assign cdoSendUsingPort is set to 2, i.e., send using SMTP (25) port
Const cdoSendUsingPort = 2

‘* Create CDO Objects and assign to variables
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields

‘* Assign values to Flds class properties

With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = sSMTPServerName
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 25
.Update
End With

‘* Assign message properties and Send the mail
With iMsg
Set .Configuration = iConf
.Fields("urn:schemas:httpmail:importance").Value = 2 ‘Setting Mail importance to High (2)
.Fields.Update
.To = strTo
.From = "AdminAlerts@company.com" ‘Fake, but make-sense email FROM address
.Sender = "Administrator@company.com" ‘Return Email address
.Subject = strSub
.TextBody = strBody
.Send
End With

End Sub

Changing WINS Server address to a bunch of Servers using VBScript


When my company started Active Directory project, we setup a new WINS server running on Windows 2003 server. We replaced our old Windows NT WINS server with new Windows 2003 server.

 

It’s easy to change the new WINS server information to the Desktops. DHCP server was the easy place to distribute the WINS server to all Desktop in one shot. BUT, What about the Servers in Data center with manual IP address mapping? Here I come with a script as below.

 

I used WMI objects to get the network properties and change the WINS address.

 

If you want to reuse this script, you need the following information ready.

  1. ServersList.txt – a text file with server names one in each line
  2. Primary and Secondary WINS server IP address
  3. First two or three octects of your production network IP address

The third requirement is little tricky. If your production network IP address of a server is 192.168.0.44, then you need to provide "192.168" to the script (check the script). If the IP Address goes like this 10.20.30.10, then you need to provide "10.20.30". I hope you get the idea.

 

I always create a log file with these kinds of scripts. This script will create a log file in running directory as WinsChange.log. It’s very handy to check back which servers were applied with new WINS and which ones failed (got to do manually).

 

CAUTION: This script works only Windows 2000 and above OSes.

 

You need to change the values in this script where you find “<<<<<” in comments

 

‘ Script Purpose: To change the WINS server information in Network properties to a bunch of computers/servers

‘ Written by: Anand Venkatachalapathy

On Error Resume Next

 

Dim fso, fin, fout

Set fso = CreateObject("Scripting.FileSystemObject")

Set fin = fso.OpenTextFile("ServerList.txt", 1, True)

Set fout = fso.OpenTextfile("WinsChange.log",2, True)

 

Do While NOT fin.AtEndOfStream

            ChangeWINS(fin.ReadLine)

Loop

 

fin.Close

fout.Close

 

Sub ChangeWINS(strComputer)

WScript.Echo "———" & strComputer & "——————"

fout.WriteLine "———" & strComputer & "——————"

 

strWINSPrimaryServer = "xx.xx.xx.xx"          ‘<<<Provide your primary WINS server IP address

strWINSSecondaryServer = "yy.yy.yy.yy"      ‘<<<Provide your secondary WINS server IP address

 

Set objWMIService = GetObject("winmgmts:" _

 & "{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")

Set colNicConfigs = objWMIService.ExecQuery _

 ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

 

WScript.Echo VbCrLf & "Host Name: " & strComputer & VbCrLf & _

 "  Attempting to set WINS primary and secondary servers …"

 

For Each objNicConfig In colNicConfigs

 

            strIPAddress = Join(objNicConfig.IPAddress,",")

            WScript.Echo "Working on network interface: " & strIPAddress

            fout.WriteLine "Working on network interface: " & strIPAddress

            If InStr(strIPAddress,"x.x") > 0 then                         ‘<<<<< Provide your starting two octects of IP address

                                                                                                ‘This is important, because we want to change the IP address only

                                                                                                ‘ to production network card.  This logic will skip the backup area network

                                                                                                ‘cards, loopback cards and disabled network cards

                        WScript.Echo VbCrLf & "  Network Adapter " & objNicConfig.Index & VbCrLf & "    " & objNicConfig.Description

                        fout.WriteLine "  Network Adapter " & objNicConfig.Index & "    " & objNicConfig.Description

                        intSetWINSServer = objNicConfig.SetWINSServer(strWINSPrimaryServer, strWINSSecondaryServer)

 

                        If intSetWINSServer = 0 Then

                                    WScript.Echo "    Successfully set WINS servers."

                                    fout.WriteLine "    Successfully set WINS servers."

                        ElseIf intSetWINSServer = 1 Then

                                    WScript.Echo "    Successfully set WINS servers." & VbCrLf & "    Must reboot."

                                    fout.WriteLine "    Successfully set WINS servers." & VbCrLf & "    Must reboot."

                        Else

                                    WScript.Echo "    Unable to set WINS servers."

                                    fout.WriteLine "    Unable to set WINS servers."

                        End If

            End If

Next

 

WScript.Echo VbCrLf & String(80, "-")

 

Set colNicConfigs = objWMIService.ExecQuery _

 ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

 

For Each objNicConfig In colNicConfigs

            WScript.Echo VbCrLf & _

            "  Network Adapter " & objNicConfig.Index & VbCrLf & _

            "    " & objNicConfig.Description

            WScript.Echo "    Primary WINS Server: " & objNicConfig.WINSPrimaryServer

            WScript.Echo "    Secondary WINS Server: " & _

            objNicConfig.WINSSecondaryServer

Next

 

End Sub