PST Find,Rename and Move

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Thu Aug 23, 2018 7:39 am

So I have added a Try Catch to help with error handling on AD user find Its not 100% clean but its working as intended. What I am also needing is during the steps to output each pst file with the user it belongs to as well as some user information to a global variable that is a sum of all the pst's that is processed through the try / catch and moved.

Not sure if that makes sense or not.

At the end of the Foreach where its processing the user folders i need it to gather data.
User's UserPrincipalName, the Name of the PST and a Folder Column that is the pst name minus the .pst. Add that to a global array so we can copy and past the output to a csv, manipulate table headings and use it to as the user mapping file for pst uploads into o365/exchange online.

Not sure how to get the array to do that.

User avatar
jvierra
Posts: 13736
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: PST Find,Rename and Move

Post by jvierra » Thu Aug 23, 2018 9:44 am

Unfortunately you are not asking a question. You are making a lot of statements about what you would like to do. Most of what you want is quite vague. What is it that you don't understand abut arrays? What do you mean by copy and paste to a CSV?

User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Thu Aug 23, 2018 11:07 am

I will sort it out myself.

User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Thu Aug 23, 2018 12:41 pm

jvierra,

This is what I was referring to.
I added line 25 to initiate the array and then line 51 to add the current file being processed to the array and then lines 62-68 to produce a way of visually verifying that the files that were supposed to be copied are what was copied. That both source files and destination files match in size. I could write a compare step. My question was or should have been "How do i create an array that will capture the file and its properties that is to copied when it is processing through an a foreach loop." I think I figured it out. If you would like to take a look and tell me if it looks about right that is cool.

Code: Select all

<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.153
Created on: 8/15/2018 3:12 PM
Created by: admdbr
Organization:
Filename:
===========================================================================
.DESCRIPTION
PST Migration Script.
#>
$searchClasses = "UNC Search", "File Search"
$c = 1
$searchClasses | Foreach {
Write-Host $c.ToString() -NoNewLine
Write-Host " --- " -NoNewLine
Write-Host $_ -ForegroundColor Green
$c++
}

[int]$searchClass = Read-Host "Select the search class"
$choice = $searchClasses[$searchClass - 1]
Write-Host $choice -ForegroundColor Yellow
$pstData = @()
## BUILD USER FOLDER LIST ##
If ($choice -eq "UNC Search")
{
$userFilePath = Read-Host "Enter UNC Path to User Folders: (Example: \\Thermon.local\USSM\HOME)"
$destination = Read-Host "Enter Destination Folder Path: (Excample: \\Thermon.local\USSM\HOME\PSTs)"
$UserFolders = Get-ChildItem -Path $userFilePath -Directory
$UserFolders | foreach {
Try
{
$user = Get-ADUser -Identity $_.Name -Properties *
$homeDir = $userFilePath + "\" + $_
$filter = "*.pst"
$n = 1
$userPSTs = Get-ChildItem -Path $homeDir -Filter $filter -Recurse
$userPSTs | foreach {
$fullName = $_.FullName
$oldName = $_.Name
$newName = $_.Name
$newName = $newName.Replace(".pst", "$n.pst")
$moveName = $newName
Rename-Item -NewName $newName -Path $fullName
$fullName = $fullName.Replace("$oldName", "$newName")
$newName = $user.UserPrincipalName + "_" + $newName
Rename-Item -NewName $newName -Path $fullName
$fullName = $fullName.Replace("$moveName","$newName")
$pstData += Get-Item -Path $fullName
Copy-Item -Path $fullname -Filter $filter -Destination $destination
$n++
}
}
CATCH
{
Write-Host "User $_.Name Not Found in ActiveDirectory" -ForegroundColor Yellow
}
}
## Create Output for PST Mapping File for O365 Import Job ##
$pstData | select Name,Length,FullName | Out-GridView
$desData = Get-ChildItem -Path $destination -Filter $filter
$desData | select Name,Length | Out-GridView
Write-Host "Total PST Files in Destination: " ($desData).count
Write-Host "Total PST Files in Source of Active Users: " ($pstData).Count
## Verification Check ##
$choicDelete = Read-Host "Verification Completed Successful? (Yes/No)"
If ($choicDelete -eq "Yes")
{
$pstData | foreach {
Remove-Item -Path $_.FullName -Confirm:$false
}
If ($choiceDelete -eq "No")
{
Write-Host "You have Selected NO. Script is Terminating!!!!!!"
}
}
}

If ($choice -eq "File Search")
{
$File = Read-Host "Enter File Name and Path to Search: (Example: \\Thermon\USSM\ITData\PSTMigration\User_Group1.csv"
$destination = Read-Host "Enter Destination Folder Path: (Excample: \\Thermon.local\USSM\HOME\PSTs)"
$users = Import-Csv -Path $File
$users | foreach {
Try
{
$user = Get-ADUser -Identity $_.samAccountName -Properties *
$homeDir = $user.HomeDirectory
$filter = "*.pst"
$n = 1
$userPSTs = Get-ChildItem -Path $homeDir -Filter $filter -Recurse
$userPSTs | foreach {
$fullName = $_.FullName
$oldName = $_.Name
$newName = $_.Name
$newName = $newName.Replace(".pst", "$n.pst")
$moveName = $newName
Rename-Item -NewName $newName -Path $fullpath
$fullName = $fullName.Replace("$oldName", "$newName")
$newName = $user.UserPrincipalName + "_" + $newName
Rename-Item -NewName $newName -Path $fullName
$fullName = $fullName.Replace("$moveName", "$newName")
$pstData += Get-Item -Path $fullName
Copy-Item -Path $fullName -Filter $filter -Destination $destination
$n++
}
}
CATCH
{
Write-Host "User $_.Name Not Found in ActiveDirectory" -ForegroundColor Yellow
}
}
## Create Output for PST Mapping File for O365 Import Job ##
$pstData | select Name, Length, FullName | Out-GridView
$desData = Get-ChildItem -Path $destination -Filter $filter
$desData | select Name, Length | Out-GridView
Write-Host "Total PST Files in Destination: " ($desData).count
Write-Host "Total PST Files in Source of Active Users: " ($pstData).Count
## Verification Check ##
$choicDelete = Read-Host "Verification Completed Successful? (Yes/No)"
If ($choicDelete -eq "Yes")
{
$pstData | foreach {
Remove-Item -Path $_.FullName -Confirm:$false
}
If ($choiceDelete -eq "No")
{
Write-Host "You have Selected NO. Script is Terminating!!!!!!"
}
}
}

User avatar
jvierra
Posts: 13736
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: PST Find,Rename and Move

Post by jvierra » Thu Aug 23, 2018 12:58 pm

What array are you asking about? It sounds more like you are trying to create custom objects.

To create a collection of objects use:
$myobjects = @()

Add to the collection like this:
$myobjects += $mycustomobject

User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Thu Aug 23, 2018 1:11 pm

Okay that is what I wanted to know.
Now they want me to add a self comparison to it. I am not sure how to accomplish this. I have done some reading but not sure how to do it.
They would like to compare the source files that were added to the $pstData array with the capture of the $destData array and verify file sizes (length)
What would be the right way to do that? Would compare-object? Any reference / direction would be helpful.

User avatar
jvierra
Posts: 13736
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: PST Find,Rename and Move

Post by jvierra » Thu Aug 23, 2018 1:16 pm

Compare-Object would be the method.

User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Mon Aug 27, 2018 8:48 am

Okay here is I hope to be my last question.

How do you wrap a variable in quotes.
I am trying to have an input requirement of the SAS URL for pst upload and then kick off an AzCopy command but the command requires that the SAS URL be wrapped in quotes. I get various errors relating to that variable and i believe its related to the missing quotes.

Thanks,
Dwight

User avatar
dwight.brookland
Posts: 15
Joined: Sun Mar 03, 2013 12:43 pm

Re: PST Find,Rename and Move

Post by dwight.brookland » Mon Aug 27, 2018 9:07 am

Before you ask, I wanted to provide the code.

Code: Select all

$sasURL = Read-Host "Please enter the SAS URL:"
$pstServer = Read-Host "Please enter server PSTs reside on. "
$sasURL = $sasURL.Replace("ingestiondata", "ingestiondata/$pstServer")
Write-Host $sasURL
Pause
Invoke-Command -ComputerName $pstServer -ScriptBlock {
CD "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy"
Write-Host
.\AzCopy.exe /Source:"$destination" /Dest:"$sasURL" /V:"$Log" /Y
Return
}

User avatar
jvierra
Posts: 13736
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: PST Find,Rename and Move

Post by jvierra » Mon Aug 27, 2018 10:13 am

When passing variables it is not necessary to use quotes. You also need to pass the variable to the remote either as an argument or with the "using " scope identifier.

$using:sasUrl

Locked