Closing open Lotus Notes file
The users at a certain customer have a problem with reopening Lotus Notes if their session is not closed properly (e.g. because of a crash of a terminal server). They keep receiving the error message “Domino Server still running” until we close the open files.
I’ve been writing a script over time to automate this process which becomes quickly annoying after you’ve done it a couple of times.
More specifically, the script will:
- Connect to a GC to get domain and display name (ADFind)
- Connect to a DC to get home directory (ADFind)
- Derive server name from the previous query via string manipulation (Set)
- Kill PsExec if it’s already running (SC)
- Find the physical disk (PsExec)
- List open Notes files and ask if you whan to close them (PsFile)
- Close the files if after you confirmed you wanted to do so (PsFile)
- Quit
- Last but not least, it will put a comment on the clipboard for easy pasting in the incident management tool ;-)
Prerequisites are both ADFind and PsTools.
Well, here it is:
1: ::========================================================================================================
2: :: AUTHOR
3: :: Koen Vermoesen
4: :: koen.vermoesen@nospam.com
5: :: 2008-04-24
6: ::========================================================================================================
7: :: SCRIPT
8: :: Close open lotus notes files
9: ::========================================================================================================
10: :: PREREQUISITES
11: :: ADFind http://www.joeware.net/freetools/tools/adfind/index.htm
12: :: PsTools http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx
13: ::========================================================================================================
14: :: CHANGE HISTORY:
15: :: 2008-04-24 Initial version
16: :: 2008-04-25 Use %temp% to avoid writing to a network share all the time
17: :: 2008-05-07 Added a todo for the script
18: :: 2008-05-13 Call another script to verify & close psexec if it's already running
19: :: 2008-05-13 Goto end (skip closing) when no open files found
20: :: 2008-05-13 Print user's diplay name as a means to cross check
21: :: 2008-05-14 Removed last reference to temporary file
22: :: 2008-07-31 Started using ADFind to make script work across domains
23: :: 2008-07-31 Removed dependency on other scripts for easy sharing with colleagues
24: :: 2008-09-16 Goto end after closing files + use variable for Title
25: :: 2008-10-06 Provide some help when no parameters are being passed
26: :: 2008-10-07 Used hardcoded path for DFS
27: :: 2008-10-07 Check if very first query returns a valid resullt. Jump to help (skip remainder of script) if not
28: :: 2008-10-07 Update Help: hardcoded DFS values + for loop example for running against a batch of users
29: :: 2008-10-27 Use clip.exe to store some comment on the clipboard for easy pasting in the incident
30: ::========================================================================================================
31: :: TO DO
32: :: Integrate logic for working on a batch of users.
33: ::========================================================================================================
34:
35: @echo off
36: setlocal EnableDelayedExpansion
37:
38: :: Setting some variables
39: Set StrTitle=Close open Lotus Notes files
40: Set strHomeDirAB=FileServer01
41: Set strHardDiskAB=E:
42:
43: Cls
44: Title %StrTitle%
45:
46: ::Saving the input parameter to variable
47: Set StrUserName=%1
48: If "[%strUserName%]"=="[]" Goto Help
49: Set Return=return1
50: Goto SubEcho
51: :return1
52:
53: :: Looking up Distinguished Name & Display Name
54: For /F "tokens=1,2 delims=;" %%I in ('adfind -nodn -csv -nocsvheader -csvnoq -csvdelim ^; -gc -s subtree -b dc^=domain^,dc^=tld -f ^"sAMAccountName^=%StrUserName%^" distinguishedName displayName') Do Set StrDistingName=%%I & Set StrDisplayName=%%J
55: If "[%StrDisplayName%]"=="[]" Echo. & Echo No valid user object found; please check the username. & Echo. & Goto Help
56: Set StrBaseDN=%StrDistingName:~-26%
57: Set Return=return2
58: Goto SubEcho
59: :return2
60:
61: :: Looking up Home Directory
62: Set StrTLD=%StrBaseDN:~22,3%
63: Set StrRoot=%StrBaseDN:~15,3%
64: Set StrDomain=%StrBaseDN:~3,8%
65: For /F %%I in ('adfind -nodn -csv -nocsvheader -csvnoq -s subtree -b dc^=%StrDomain%^,dc^=%StrRoot%^,dc^=%StrTLD% -f ^"sAMAccountName^=%StrUserName%^" homeDirectory') Do Set StrHomeDirectory=%%I
66: Set Return=return3
67: Goto SubEcho
68: :return3
69:
70: :: Looking up Home Server
71: IF /I "%StrDomain%"=="subdomain3" (Set StrHomeServer=%strHomeDirAB%) Else (For /F "tokens=1 delims=\" %%I in ("%StrHomeDirectory%") Do Set StrHomeServer=%%I)
72: Set Return=return4
73: Goto SubEcho
74: :return4
75:
76: :: Ensuring PsExec is not running on Home Server
77: echo.
78: For /F "Tokens=2" %%I in ('sc \\%StrHomeServer% query psexesvc ^| find "SERVICE_NAME"') Do Set StrPsexecExists=%%I
79: If /I "%StrPsexecExists%"=="psexesvc" (echo PsExec running on the remote host; killing it. & sc \\%StrHomeServer% stop psexesvc & sc \\%StrHomeServer% delete psexesvc) else (echo PsExec is not running on the remote host.)
80:
81: :: Looking up Physical Disk
82: echo.
83: IF /I "%StrDomain%"=="subdomain3" (Set StrHardDisk=%strHardDiskAB%) Else (For /F "tokens=2 delims=\ " %%I in ('psexec \\%StrHomeServer% net share ^| find /i "%StrUserName%"') Do Set StrHardDisk=%%I)
84: Set Return=return5
85: Goto SubEcho
86: :return5
87:
88: :: Listing open Lotus Notes Files
89: IF /I "%StrDomain%"=="subdomain1" (set StrNotesPath=%StrHardDisk%\folder\%StrUserName%\windows\NotesR6)
90: IF /I "%StrDomain%"=="subdomain2" (set StrNotesPath=%StrHardDisk%\folder\folder\%StrUserName%\notes\data)
91: IF /I "%StrDomain%"=="subdomain3" (set StrNotesPath=%StrHardDisk%\folder\%StrUserName%\WINDOWS\NotesR6)
92: Set StrOpenFiles=
93: For /F "tokens=2 delims=] " %%I in ('psfile \\%StrHomeServer% %StrNotesPath% ^| find /i "] %StrNotesPath%"') Do Set StrOpenFiles=!StrOpenFiles!%%I
94: Set Return=return6
95: Goto SubEcho
96: :return6
97: echo.
98: IF /I "%StrOpenFiles%"=="" (Echo No open files found. & goto :end)
99: echo Open Files:
100: For %%I in (%StrOpenFiles%) do echo %%I
101:
102: :: Closing open Lotus Notes Files
103: echo.
104: Set /P StrConfirmClose="Press <c> to close these files, <enter> key will SKIP this step."
105: IF /I "%StrConfirmClose%"=="c" (psfile \\%StrHomeServer% %StrNotesPath% -c) ELSE Goto end
106: Set Return=return7
107: Goto SubEcho
108: :return7
109: echo.
110: echo Open Lotus Notes files closed!
111: echo Open Lotus Notes files for user %StrUserName% on server %StrHomeServer% closed. | clip
112: Goto End
113:
114: :: Procedure printing the different values determined by script
115: :SubEcho
116: cls
117: Title %StrTitle%
118: Echo User: %StrUserName%
119: Echo Name: %StrDisplayName%
120: Echo BaseDN: %StrBaseDN%
121: Echo TLD: %StrTLD%
122: Echo Root: %StrRoot%
123: Echo Domain: %StrDomain%
124: Echo HomeDir: %StrHomeDirectory%
125: Echo Server: %StrHomeServer%
126: Echo Disk: %StrHardDisk%
127: Echo Path: %StrNotesPath%
128: Goto %Return%
129:
130: :Help
131: Title %strTitle%
132: Echo You should call this script from the command line passing the name of the user to unblock as a parameter. (e.g. "killnotes user1980"). The script will then fetch some data, list the open lotus notes files and ask you wheter or not you want to close them.
133: Echo.
134: Echo More specifically, the script will:
135: Echo 1. Connect to GC to get domain and display name (ADFind)
136: Echo 2. Connect to DC to get home directory (ADFind)
137: Echo 3. Get servername via string manipulation (Set)
138: Echo 4. Kill PsExec if it's already running (SC)
139: Echo 5. Find the physical disk (PsExec)
140: Echo 6. List open Notes files and ask if you whan to close them (PsFile)
141: Echo 7. Close the files if you confirmed you wanted to do so (PsFile)
142: Echo 8. Quit
143: Echo.
144: Echo If you want to apply this script on a number of users then I recommend saving them in a file "userlist.txt" (1 user per line). You can then use a for loop to launch the script:
145: Echo.
146: Echo for /F %%i in (userlist.txt) do killnotes %%i
147: Echo.
148: Echo IMPORTANT: Physical Disk (%strHardDiskAB%) and Server Name (%strHomeDirAB%) for AB are HARDCODED. These values need to be adopted in the script if the design ever changes.
149: Echo.
150: Echo PS1: The script will print the values of the different variables to allow you to monitor the progress.
151: Echo PS2: If the script halts for a moment it's because of number of connections being made using PsTools.
152: Echo.
153:
154: ::Deleting variables
155: :END
156: Echo.
157: Echo Quitting...
158: Endlocal
There’s still some room for improvement obviously. The hard coded DFS information, for instance, should be replaced with some decent logic (there are very few users on this infra however, so I didn’t invest to much time in that part).
http://www.robvanderwoude.com/ proved very helpful while writing this script.
Can I take part of your post to my blog?really like this,mate
Sure you can! But do put a link back to my blog please.