0

仕事で新しいExchangeサーバーを選択したので、上司からすべてのコンピューターに移動して、開いているすべてのPSTファイルを新しいサーバーのフォルダーに手動で移動するように指示しました。明らかな理由で、これをスクリプト化する方が簡単だと判断しました。少し調べてみると、少し調整するだけでよいスクリプトが1つ見つかりました(http://halfloaded.com/blog/logon-script-move-local-pst-files-to-network-share/にあります)。)しかし、実際には必要のないものがたくさんあったので(ラップトップで実行されているかどうかをチェックし、ローカルフォルダーにのみ影響するなど)、メインロジックを自分のバージョンに共食いしました。これらの健全性チェック。私が遭遇している問題は、2つの一見同じループが異なる回数繰り返されていることであり、それが問題を引き起こします。これが私が持っているものです

Option Explicit
Const OverwriteExisting = True

' get username, will use later
Dim WshNetwork: Set WshNetwork = wscript.CreateObject("WScript.Network")
Dim user: user = LCase(WshNetwork.UserName)
Set WshNetwork = Nothing

' network path to write pst files to
Dim strNetworkPath : strNetworkPath = "\\server\folder\"
'Fix network path if forgot to include trailing slash...
If Not Right(strNetworkPath,1) = "\" Then strNetworkPath = strNetworkPath & "\" End If

' initiate variables and instantiate objects
Dim objOutlook, objNS, objFolder, objFSO, objFName, objTextFile, pstFiles, pstName, strPath
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.CreateTextFile("c:\My\Desktop\pst_script_log.txt " , True)
Set objOutlook = CreateObject("Outlook.Application")
Set objNS = objOutlook.GetNamespace("MAPI")
Dim count : count = -1

' Enumerate PST filesand build arrays
objTextFile.Write("Enumerating PST files" & vbCrLf)
For Each objFolder in objNS.Folders
    If GetPSTPath(objFolder.StoreID) <> "" Then
        pstFiles = GetPSTPath(objFolder.StoreID)
        pstName = objFolder.Name
        count = count + 1
        objTextFile.Write(count & "  " & pstFiles & vbCrLf)
        ReDim Preserve arrNames(count)
        arrNames(count) = pstName
        ReDim Preserve arrPaths(count)
        arrPaths(count) = pstFiles
        objOutlook.Session.RemoveStore objFolder
    End IF
Next

' closes the outlook session
objOutlook.Session.Logoff
objOutlook.Quit
Set objOutlook = Nothing
Set objNS = Nothing

' quits if no pst files were found
If count < 0 Then
    wscript.echo "No PST Files Found."
    wscript.Quit
End If

objTextFile.Write("moving them" & vbCrLf)

' moves the found pst files to the new location
Dim pstPath
For Each pstPath In arrPaths
    On Error Resume Next
        objTextFile.Write(pstPath & vbCrLf)
        objFSO.MoveFile pstPath, strNetworkPath
        If Err.Number <> 0 Then
            wscript.sleep 5000
            objFSO.MoveFile pstPath, strNetworkPath
        End If
    Err.Clear
    On Error GoTo 0
Next
Set objFSO = Nothing

' sleep shouldn't be necessary, but was having issues believed to be related to latency
wscript.sleep 5000
'Re-open outlook
Set objOutlook = CreateObject("Outlook.Application")
Set objNS = objOutlook.GetNamespace("MAPI")

'Re-map Outlook folders
For Each pstPath In arrPaths
    objTextFile.Write("Remapping " & pstPath & " to " & strNetworkPath & Mid(pstPath, InStrRev(pstPath, "\") + 1) & vbCrLf)
    objNS.AddStore strNetworkPath & Mid(pstPath, InStrRev(pstPath, "\") + 1)
Next

count = -1

For Each objFolder In objNS.Folders
    If GetPSTPath(objFolder.StoreID) <> "" Then
        count = count + 1
        objTextFile.Write("Renaming " & GetPSTPath(objFolder.StoreID) & " to " & arrNames(count) & vbCrLf)
        objFolder.Name = arrNames(count)
    End If
Next

objOutlook.Session.Logoff
objOutlook.Quit
objTextFile.Write("Closing Outlook instance and unmapping obj references...")
Set objFolder = Nothing
Set objTextFile = Nothing
Set objOutlook = Nothing
Set objNS = Nothing
wscript.echo "Done."
wscript.Quit

Private Function GetPSTPath(byVal input)
    'Will return the path of all PST files
    ' Took Function from: http://www.vistax64.com/vb-script/
    Dim i, strSubString, strPath
    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

問題のあるループは24行目と81行目にあります。特定のエラーは、最初のループよりも2番目のループの方がカウントが増えることです。ただし、これは、最初のループの反復が不足していて、最後のPSTファイルが欠落しているためです。このコードのほとんどを見つけたサイトで同様の問題を抱えている人々は、特定の場所にwscript.sleep関数を追加することで彼らは助けになったと言いましたが、私は彼らの推奨場所でそのような運がなかったので、彼らの問題は私と同じではありません。

私のコードで何がうまくいかないのか助けていただければ幸いです。私は、私が見ない他の問題を修正する方法についての提案を受け入れており、このようなことを行うためのより良い方法があると思います。

EDI:私の問題についてさらに調査した後、24行目のループ内でRemoveStoreを実行することで、objNS.Foldersの値を変更しているようです(これは理にかなっています)。これを回避するには、objFolderアイテムを保存する必要があります。削除して別のループで行う必要があります。今の問題は、私がそれを行う方法がわからないということです、私は試しました

        [line 35]
        ReDim Preserve arrFolders(count)
        arrFolders(count) = objFolder
    End If
Next

For Each objFolder in arrFolders
    objOutlook.Session.RemoveStore objFolder
Next

ただし、RemoveStoreに関してType Mismatchエラーが発生するため、オブジェクトが必要な方法で保存されていないと思います。何か案は?

4

2 に答える 2

1

FWIW-ネットワーク上のPSTへの接続はサポートされていません。http://support.microsoft.com/kb/297019/en-usおよびhttp://blogs.technet.com/b/askperf/archive/2007/01/21/network-stored-pst-files-donを参照してください-t-do-it.aspx

于 2011-11-11T06:56:01.600 に答える
0

それで、最終的にこれを正しく機能させました(または十分に右に近づけました)。ブラッドからのコメントで述べたように、PSTファイルと私がここに持っているものをディスクで検索する必要があります。この方法は、ユーザーがOutlookで開いているPSTファイルにのみ影響し、コンピューター上のすべてのPSTファイルには影響しません。編集で述べたように、objOutlook.Session.RemoveStoreがobjNS.Foldersの値を変更していたため、最初のForループが壊れていました。enumartionループの外でこれを行う必要があります。そうしないと、一部が壊れて見落とされます(また、一部を再マッピングするときに誤ったラベルが付けられます)。また、そのループの外側では、objFolderをMAPIFolderオブジェクトとして再定義する必要があります。そうしないと、作業サンプルを削除しようとしたときにTypeMismatchエラーが発生します。

' Enumerate PST filesand build arrays
objTextFile.Write("Enumerating PST files" & vbCrLf)
For Each objFolder in objNS.Folders
If GetPSTPath(objFolder.StoreID) <> "" Then
    count = count + 1
    pstFiles = GetPSTPath(objFolder.StoreID)
    pstName = objFolder.Name
    pstFolder = objFolder
    objTextFile.Write(count & "  " & pstFiles & vbCrLf)
    ReDim Preserve arrNames(count)
    arrNames(count) = pstName
    ReDim Preserve arrPaths(count)
    arrPaths(count) = pstFiles
    'objOutlook.Session.RemoveStore objFolder
End If
Next

For Each pstName in arrNames
set objFolder = objNS.Folders.Item(pstName)
objNS.RemoveStore objFolder
Next
set objFolder = Nothing
于 2011-06-21T12:28:31.427 に答える