I need a script to get Outlook pst names from remote computers

I would like to use a script to get the names (including path), sizes and modified dates of all *.pst files on the remote computers. Since I would like to get familiar with Powershell, I would prefer a Powershell script but a vbs script is ok too.

I have seen some scripts which can get this information from the WMI database. If that would be faster than scanning the entire C:\ drive then this is good but either way is fine with me.

I would like the script to get the computer names to scan from a text file called computers.txt which exists in the same directory as the script.

I would like the output to be placed in a .csv file in the same directory where the script exists.

I only want the script to look on the C:\ drive, not mapped drives.

Thanks,
Don
donanderAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Darrell PorterEnterprise Business Process ArchitectCommented:
So you could do VBScript most easily using a For /F loop thusly:

FOR /F %a in (.\Computer.txt) do EnumerateRemotePST.VBS %a >> Output.log

With all due respect, nothing less than scanning the entire drive will give you all existing PST files on the remote machine.

If you have PSEXEC.EXE from Microsoft's PSTools then you can easily perform a scan of the drive and pipe the output to the global log file along with the name of the remote machine.

If you NEED a powershell script to do this, I can likely write one up later tonight.
0
footechCommented:
I think WMI is going to be the fastest for you.  It wasn't too long ago that I learned about this method.
Get-WmiObject Cim_DataFile -Filter "drive = 'c:' AND extension ='pst'" -computername (Get-Content computers.txt) |
 Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,@{n="LastModified";e={([wmi]"").ConvertToDateTime($_.LastModified)}} |
 Export-CSV files.csv -notype

Open in new window


Dates from WMI are simpler if you have PS 3.0, and you use Get-CimInstance instead of Get-WmiObject.
Get-CimInstance cim_datafile -Filter "drive = 'c:' AND extension ='pst'" -computername (Get-Content computers.txt) |
 Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,LastModified |
 Export-CSV files.csv -notype

Open in new window

0
donanderAuthor Commented:
Hi footech,
So just to clarify, I can copy the code into notepad, save with .ps1 extension and double-click? Or do I need to run from command line?
Thanks,
Don
0
Introducing the "443 Security Simplified" Podcast

This new podcast puts you inside the minds of leading white-hat hackers and security researchers. Hosts Marc Laliberte and Corey Nachreiner turn complex security concepts into easily understood and actionable insights on the latest cyber security headlines and trends.

footechCommented:
.PS1 files are associated with Notepad by default, so double-clicking won't run it.  You'll need to have the execution policy set to allow scripts to run before you can a .PS1 file.  I suggest googling how to get started in Powershell if you're not that far yet.  If you just open a PS console you can run the code.
0
donanderAuthor Commented:
I copied and pasted the code at the Powershell prompt and pressed Enter. It has been about 3 hours and it seems like it is not doing anything. I don't see the .csv file created yet. Maybe I didn't do this correctly.

C:\DonTools>powershell
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS C:\DonTools> Get-CimInstance cim_datafile -Filter "drive = 'c:' AND extension ='pst'" -computername (Get-Content computers.txt)
 |
>>  Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,LastModified |
>>  Export-CSV files.csv -notype
>>

I think I do have PS 3 from the info below.

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      3.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18444
BuildVersion                   6.2.9200.16481
PSCompatibleVersions           {1.0, 2.0, 3.0}
PSRemotingProtocolVersion      2.2
0
footechCommented:
Yep, you do have PS 3.0.  If you only had 2.0 you would have gotten an error immediately.
I tested the script against a couple remote machines and it worked fine.  It returned fairly quickly (maybe a minute), where the C: drives were between 40 and 150 GB.
Did you press Enter at the last >>?  With a multi-line command you finish with an empty line.
PS console
0
donanderAuthor Commented:
Ok, I pasted the code below at the PS prompt again. I pressed Enter and got the additional >>. After about 20 seconded I got the error below. I tried a machine not on my subnet and a machine on my subnet. Looking on my computer I don't see WinRM service but I do see "Windows Remote Management (WS-Management)" which I think must be the same. It is set to manual and that jibes with information I got from the Internet. If mine is manual then I am sure the other computers here are manual, so it appears this won't work because of that. I know that in the past someone on Experts Exchange made a vbscript (or maybe just a command line batch file) to get the size of the WMI file (just the size of the file, not using WMI) on computers here and that worked, so maybe vbscript is the way to go.

PS C:\DonTools\PST-Find-Script> Get-CimInstance cim_datafile -Filter "drive = 'c:' AND extension ='pst'" -computername (Get-Conten
t computers.txt) |
>>  Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,LastModified |
>>  Export-CSV files.csv -notype
>>
Get-CimInstance : WinRM cannot complete the operation. Verify that the specified computer name is valid, that the computer is
accessible over the network, and that a firewall exception for the WinRM service is enabled and allows access from this
computer. By default, the WinRM firewall exception for public profiles limits access to remote computers within the same local
subnet.
At line:1 char:1
+ Get-CimInstance cim_datafile -Filter "drive = 'c:' AND extension ='pst'" -comput ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ConnectionError: (:) [Get-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80338126,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
    + PSComputerName        : CP-A04102

PS C:\DonTools\PST-Find-Script>
0
footechCommented:
Yes, WinRM is Windows Remote Management.  My environments are set up to be able to use PowerShell Remoting, and so communication using WSMan is allowed.  It's possible to modify the CIMSessionOptions to use WMI (DCOM) instead of WinRM (WSMan), but for simplicity's sake, I'll just recommend that you use the example I posted which uses Get-WmiObject.
0
donanderAuthor Commented:
Ok, but WinRM won't work unless that service is running right? I don't have the authority to create a GPO to set that service to Auto on all the computers I am trying to scan. Or maybe I'm not understanding.
0
footechCommented:
It requires more than that.  That's why I'm recommending a different method to communicate over DCOM.
0
Darrell PorterEnterprise Business Process ArchitectCommented:
Can you use PSEXEC.EXE to perform a NET START "ServiceName" on each of the computers prior to running the powershell script?

You could just pass the file with the list of computers as part of the argument for PSEXEC.
0
donanderAuthor Commented:
footech:

Sorry, I did not read your previous comment carefully. When I use the Get-WmiObject version it works. To start with I tried putting just 3 computers in the text file and got the results in about 10 minutes. Then I tried 47 computers. This took about 2 hours and came back with about 24 computers that contained .pst files. Sweet!! Fortunately only 2 or 3 look like they are active. The total list of computers to scan is 749 so that will probably take overnight or over the weekend but that's fine.

I saw the error below 9 times in the command window while the script was running. I think this is probably due to the machine being off or otherwise unresponsive. Since the error doesn't include the computer name is it possible for the script to put the name of computers that do not respond in the output file and put "no response" or something like that in the path column? Then we can go back and scan those again later or go visit the machine to see what's up with it.

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At C:\DonTools\PST-Find-Script\get-pst-v2.ps1:1 char:1
+ Get-WmiObject Cim_DataFile -Filter "drive = 'c:' AND extension ='pst'" -computer ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
0
footechCommented:
The below will test each computer to see if it responds to a couple pings before pulling the data.
(Get-Content computers.txt) | ForEach `
{
    If (Test-Connection $_ -Count 2 -Quiet)
    {
        Get-WmiObject Cim_DataFile -Filter "drive = 'c:' AND extension ='pst'" -computername $_ |
         Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,@{n="LastModified";e={([wmi]"").ConvertToDateTime($_.LastModified)}}
    }
    Else
    {
        "" | Select @{n="Computer";e={$_}},@{n="Name";e={"N/A"}},@{n="FileSize";e={""}},@{n="LastModified";e={""}}
    }
} | Export-CSV files.csv -notype

Open in new window

0
donanderAuthor Commented:
Thanks for the quick reply. I am on my way home now but I will try this tomorrow.
0
donanderAuthor Commented:
Hi footech,

With this latest code the Computer (computer name) column in the output file is blank.

Thanks,
Don
0
footechCommented:
You must mean only when it can't ping the machine.  Here's a modification to correct that.
(Get-Content computers.txt) | ForEach `
{
    If (Test-Connection $_ -Count 2 -Quiet)
    {
        Get-WmiObject Cim_DataFile -Filter "drive = 'c:' AND extension ='pst'" -computername $_ |
         Select @{n="Computer";e={$_.PSComputerName}},Name,FileSize,@{n="LastModified";e={([wmi]"").ConvertToDateTime($_.LastModified)}}
    }
    Else
    {
        $comp = $_
        "" | Select @{n="Computer";e={$comp}},@{n="Name";e={"N/A"}},@{n="FileSize";e={""}},@{n="LastModified";e={""}}
    }
} | Export-CSV files.csv -notype

Open in new window

0
donanderAuthor Commented:
No, I meant NONE of the machine names were there. With the last change you made the names of the machines that are not responding to ping are shown in the computer names column (with N/A in the path column) but the computer name column for machines where the paths are found are found is blank. I've attached the output file with computer names and user names replaced by other characters to de-identify the information.
files.xlsx
0
footechCommented:
Very odd.  If the first code I posted is giving you a name, then the other should as well.  It's using the exact same code in that area, and in my testing it always shows the computer name.  Oh well, we'll just always use the name from the file rather then getting it from the returned data.
(Get-Content computers.txt) | ForEach `
{
    $comp = $_
    If (Test-Connection $_ -Count 2 -Quiet)
    {
        Get-WmiObject Cim_DataFile -Filter "drive = 'c:' AND extension ='pst'" -computername $_ |
         Select @{n="Computer";e={$comp}},Name,FileSize,@{n="LastModified";e={([wmi]"").ConvertToDateTime($_.LastModified)}}
    }
    Else
    {
        "" | Select @{n="Computer";e={$comp}},@{n="Name";e={"N/A"}},@{n="FileSize";e={""}},@{n="LastModified";e={""}}
    }
} | Export-CSV files.csv -notype

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
donanderAuthor Commented:
footech,
I went back and checked the first code and it was not including the computer names either. Sorry if I gave you the wrong impression about that. The most recent code does exactly what I want!! This is really helpful. While Microsoft recommends storing PSTs locally we do not backup local workstations so we try to configure users' computers to store PSTs in their network home directory. Unfortunately sometimes we fail to configure Outlook to do this so they end up on the local workstation. We are mostly on Outlook 2010 now but previous versions had Archive enabled by default so there are quite a few "archive.pst" files on the local computers. I started the script scanning 749 workstations last night at 8:00 pm. This morning around 9:00 am it had gone about halfway so should complete sometime today. I am going to ask a new question to see if a script can copy the local PSTs to H:\mail and reconfigure Outlook to connect to them there. I'm not going to ask that here as I think that would be trying to get a "two-for-the-price-of-one".
0
donanderAuthor Commented:
footech stayed engaged with me to modify the script based on my feedback until it does exactly what I wanted. Thanks very much!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.