Перенос моей статьи, для истории, из ЖЖ (livejournal.com)

Возникла нужда централизованно получить у всех пользователей список всех подцепленых в Outlook 2003 мейлсторажей с их обьемами в Kb а также какой из них текущий (т.е. используется как деливери локейшен).


Поскольку готового решения не нашел то на свет появилось следующее коленочное решение:
У текущего профиля почтового залогиненного пользователя получаем список подцепленых хранилищ почты, узнав при этом дефолтовое и их размеры. Записываем это дело в стандартный MIF-файл и скармливаем его СМСу при следующем цикле инвентаризации.

В процессе реализации возникли некоторые траблы:
1. Например я не смог без регистрации дополнительных обьектов (CDO.DLL) узнать размеры mailbox'а.
2. Если у пользователя нету административных прав то писать в каталог %WINDIR% и ниже он никакого права не имеет, а значит передать СМСу файл инвентаризации невозможно.

Первую проблему решить по-другому пока не получилось. А вторая решилась разделением солюшена на два контекста - пользовательский (где мы получив данные скидываем их в созданный нами временный каталог) и административного, где мы перебрасываем инвентаризационнный файл в "правильный" каталог и удаляем временную директорию.

 

Итак сами инструкции:
1. создаем пэкэдж в который включаем скрипт ниже.
2. В пакете создаем две программы: stage1 (исполнять без показа окон, строго из под юзерского контекста и когда залогинен кто-либо) и stage2 (исполнять без показа окон, сторого из под административного контекста когда кто-либо залогинен, обязательно каждый раз исполнять программу stage1 перед тем как начинать эту)
3. В свойствах stage1 указываем командную строку исполнения "cscript //B //NOLOGO olk.vbs usermode"
4. В свойствах stage2 указываем командную строку исполнения "cscript //B //NOLOGO olk.vbs adminmode"
5. Создаем адверчайзмент и говорим ему исполняться с таким-же интвервалом как аппаратная инвентаризация.
6. Вуаля, наливаем сока и ждем сидя у административной консоли как в Resource Explorer'е у клиентов появится новая графа инвентаризации "Outlook Mail" с отчетом ;)


------------------------------olk.vbs start--------------------------------
Dim CurKey
CurKey = 0
Set myfso = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments</p>

If objArgs.Count < 1 Then
WScript.Echo "Outlook user mailstore inventory tool v1.0"
WScript.Echo "To use, execute with parameters:"
WScript.Echo "olk.vbs usermode - To perform actual inventory steps and create result .MIF"
WScript.Echo "olk.vbs adminmode - To move result .MIF to SMS2003 inventory agent directory"
Else
If objArgs(0) = "usermode" Then DoUSERMODEInventory()
If objArgs(0) = "adminmode" Then DoADMINMODEInventory()
End If

WScript.Quit()


Function DoUSERMODEInventory()
On Error resume next
Set olApp = GetObject("", "Outlook.Application")
If Err.Number > 0 Then
Err.clear
Set olApp = CreateObject("Outlook.Application")
End If
myfso.CreateFolder("C:\$MIFTEMP$")
Set MIFFile = myfso.OpenTextFile("C:\$MIFTEMP$\" & olApp.GetNamespace("MAPI").CurrentUser & ".mif", 2, True)
DefaultFolderName = olApp.GetNamespace("MAPI").GetDefaultFolder(6).FolderPath

MIFFile.Write "Start Component" & VbCrLf
MIFFile.Write "NAME = " + Chr(34) + "WORKSTATION" + Chr(34) & VbCrLf

Set objNS = olApp.GetNamespace("MAPI")
For Each objFolder In objNS.Folders
CurKey = CurKey + 1
PSTPath = GetPSTPath(objFolder.StoreID)
IF LEN(PSTPath) > 0 THEN
PSTSize = GetFileSize(PSTPath)
ELSE
PSTSize = 0
END IF
MIFFile.Write " Start Group" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "Outlook Mail" + Chr(34) & VbCrLf
MIFFile.Write " ID = " + CStr(CurKey) + VbCrLf
MIFFile.Write " CLASS = " + Chr(34) + "OutlookMailStatus" + Chr(34) & VbCrLf
MIFFile.Write " KEY = 1" & VbCrLf

MIFFile.Write " Start Attribute" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "FullPath" + Chr(34) & VbCrLf
MIFFile.Write " ID = 1" & VbCrLf
MIFFile.Write " TYPE = STRING(256)" & VbCrLf
If Instr(PSTPath, Chr(92)) > 0 Then PSTPath = Replace(PSTPath, Chr(92), Chr(92) & Chr(92), 1, -1, 1)
MIFFile.Write " VALUE = " + Chr(34) + PSTPath + Chr(34) & VbCrLf
MIFFile.Write " End Attribute" & VbCrLf
MIFFile.Write " Start Attribute" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "FriendlyName" + Chr(34) & VbCrLf
MIFFile.Write " ID = 2" & VbCrLf
MIFFile.Write " TYPE = STRING(256)" & VbCrLf
MIFFile.Write " VALUE = " + Chr(34) + objFolder.Name + Chr(34) & VbCrLf
MIFFile.Write " End Attribute" & VbCrLf
MIFFile.Write " Start Attribute" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "LoggedProfileUserName" + Chr(34) & VbCrLf
MIFFile.Write " ID = 3" & VbCrLf
MIFFile.Write " TYPE = STRING(256)" & VbCrLf
MIFFile.Write " VALUE = " + Chr(34) + olApp.GetNamespace("MAPI").CurrentUser + Chr(34) & VbCrLf
MIFFile.Write " End Attribute" & VbCrLf
MIFFile.Write " Start Attribute" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "Default" + Chr(34) & VbCrLf
MIFFile.Write " ID = 4" & VbCrLf
MIFFile.Write " TYPE = STRING(4)" & VbCrLf
IF InStr(DefaultFolderName, objFolder.Name) > 0 Then
MIFFile.Write " VALUE = " + Chr(34) + "YES" + Chr(34) & VbCrLf
ELSE
MIFFile.Write " VALUE = " + Chr(34) + "NO" + Chr(34) & VbCrLf
End IF
MIFFile.Write " End Attribute" & VbCrLf
MIFFile.Write " Start Attribute" & VbCrLf
MIFFile.Write " NAME = " + Chr(34) + "Size" + Chr(34) & VbCrLf
MIFFile.Write " ID = 5" & VbCrLf
MIFFile.Write " TYPE = INTEGER" & VbCrLf
MIFFile.Write " VALUE = " & CStr(PSTSize) & VbCrLf
MIFFile.Write " End Attribute" & VbCrLf

MIFFile.Write " End Group" & VbCrLf
Next

MIFFile.Write "End Component" & VbCrLf

Set objFolder = Nothing
Set objApp = Nothing

MIFFile.Close

End Function


Function DoADMINMODEInventory()
myfso.CopyFile "C:\$MIFTEMP$\*.mif", SMSAgentPath()
myfso.DeleteFolder("C:\$MIFTEMP$")
End Function

Function GetPSTPath(input)
For i = 1 To Len(input) Step 2
strSubString = Mid(input,i,2)
If Not strSubString = "00" Then
strPath = strPath & ChrW("&H" & strSubString)
End If
Next
Select Case True
Case InStr(strPath,":\") > 0
GetPSTPath = Mid(strPath,InStr(strPath,":\")-1)
Case InStr(strPath,"\\") > 0
GetPSTPath = Mid(strPath,InStr(strPath,"\\"))
End Select
End Function

Function GetFileSize(input)
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(input)
GetFileSize = f.Size / 1024
Set fso = Nothing
End Function

Function SMSAgentPath()
Set oWshShell = CreateObject("WScript.Shell")
On Error resume next
SMSAgentPath = oWshShell.RegRead("HKLM\SOFTWARE\Microsoft\SMS\Client\Configuration\Client Properties\NOIDMIF Directory")
If Err.Number <> 0 Then
SMSAgentPath = ""
End if
Set oWshShell = Nothing
End Function

------------------------------olk.vbs stop--------------------------------