Skip to content

Instantly share code, notes, and snippets.

@NathanTheGr8
Last active January 8, 2023 23:50
Show Gist options
  • Save NathanTheGr8/dd9c4600802449e9a59908e3c7ab133f to your computer and use it in GitHub Desktop.
Save NathanTheGr8/dd9c4600802449e9a59908e3c7ab133f to your computer and use it in GitHub Desktop.
#archive_dir = "C:\Outlook Archives"
$network_share = "\\some\server"
<#
Gets a list of the last 20 logins/outs. Then counts the actions by each user. Returns the user with the highiest count.
Also purge domain\ from username and any spaces
#>
function get-freq-user
{
$newest = 20
$ComputerName = $env:computername
$UserProperty = @{ n = "User"; e = { ((New-Object System.Security.Principal.SecurityIdentifier $_.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])).ToString() } }
$logs = Get-EventLog System -Source Microsoft-Windows-Winlogon -ComputerName $ComputerName -newest $newest | select $UserProperty
$logs = $logs | Group-Object user | Sort Count | Select -First 1 | Select-Object -Property Name | Out-String
$index = $logs.indexOf("\") + 1
return $logs.substring($index) -replace '\s',''
}
<#
https://social.technet.microsoft.com/Forums/scriptcenter/en-US/9b2ce16c-ac0c-4695-a4ea-acca86cd30d4/windows-powershell-pst-copy-questions?forum=ITCG
#>
function kill-outlook {
if ((Get-Process "outlook")) {
Get-Process "outlook" | stop-process –force
for ($a=1; $a -lt 100; $a++) {
Write-Progress -Activity "Working..." `
-PercentComplete $a -CurrentOperation `
"$a% complete" `
-Status "Please wait."
Start-Sleep -Milliseconds 100
}
Write-Output "Killed Outlook"
}
else {
Write-Output "Outlook is not running"
}
}
function ReleaseComObject($comobject){
$ret=1
do{
$ret=[System.Runtime.Interopservices.Marshal]::ReleaseComObject($comobject)
}while($ret -ne 0)
}
<#
https://www.adminarsenal.com/blog/secure-password-with-powershell-encrypting-credentials-part-1/
Generare secure password string and save it to a file
#>
function Generate-Secure-String {
$PasswordFile = "$PSScriptRoot\passhash.txt"
$KeyFile = "$PSScriptRoot\AES.key"
$Key = Get-Content $KeyFile
$Password = Read-Host "Enter Password" | ConvertTo-SecureString -AsPlainText -Force
$Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile
}
<#
https://www.adminarsenal.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/
Creating AES key with random data and export to file
#>
function Generate-AES-Key {
$KeyFile = "$PSScriptRoot\AES.key"
$Key = New-Object Byte[] 16 # You can use 16, 24, or 32 for AES
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file $KeyFile
}
<#
http://stackoverflow.com/questions/24992681/powershell-check-if-a-file-is-locked
Test if there is a lock on a file
#>
function Test-FileLock {
param (
[parameter(Mandatory=$true)][string]$Path
)
$oFile = New-Object System.IO.FileInfo $Path
if ((Test-Path -Path $Path) -eq $false) {
return $false
}
try {
$oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
if ($oStream) {
$oStream.Close()
}
$false
} catch {
# file is locked by a process.
return $true
}
}
function uploadArchives {
$user = Get-Freq-User
Write-Output "detected $user"
Write-Output "running from $PSScriptRoot"
kill-outlook
## Elevate
$Admin = "domain\servoce account"
$PasswordFile = "$PSScriptRoot\Passhash.txt"
$KeyFile = "$PSScriptRoot\AES.key"
$key = Get-Content $KeyFile
$cred = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $Admin, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key)
# failed flag
$failed = $false
$archives = Get-ChildItem $archive_dir
foreach ($archive in $archives){
if ([IO.Path]::GetExtension($archive) -eq ".pst"){
$new_name = "$($network_share)\$($user)-$($archive.Name)"
$source = $archive.Fullname
Write-Output "Found $source"
$date = [datetime](Get-ItemProperty -Path $source -Name LastWriteTime).lastwritetime
if ((((Get-Date) - $date).Days) -le 7){
Write-Output "Archive modified recently, Uploading"
Write-Output "source: $source"
Write-Output "dest: $new_name"
if (test-FileLock -Path $source){
Write-Output "File $source is locked!"
}
#Copy-Item -Path $source -Destination $new_name
$process = Start-Process "$psHome\powershell.exe" -Credential $cred -ArgumentList "Copy-Item -Path '$source' -Destination '$new_name'" -WindowStyle hidden -PassThru -Wait
Write-Output "ExitCode: $($process.ExitCode)"
# Return failed exit code later
if ($process.ExitCode -ne 0){
$failed = $true
}
Write-Output ""
}
else {
Write-Output "Archive has not been mounted in 7 days. Not copying"
}
}
}
# Mark as failed in SCCM if one of the archives failed to transfer
if ($failed -eq $true){
[System.Environment]::Exit(1)
}
}
## Generate csv need for O365 importing
function generate-pst-csv {
$archives = Get-ChildItem $network_share
$csvContents = @() # Create the empty array that will eventually be the CSV file
foreach ($archive in $archives){
#clear out varibles
$user_email = ""
$folder = "" #folder to be placed in in 0365
$og_file_name = "" #original file name
$flag = $false
foreach ($letter in $archive.Name.ToCharArray()){
if($letter -eq "-"){ # change from username to original filename
$flag = $true
continue
}
if($flag -eq $true){
if($letter -eq "."){
break #ignore extension
}
$og_file_name += $letter
}
else {
$user_email += $letter
}
}
$user_email += "@company.com"
$folder = "/$($og_file_name)"
$row = New-Object System.Object # Create an object to append to the array
$row | Add-Member -MemberType NoteProperty -Name "Workload" -Value "Exchange"
$row | Add-Member -MemberType NoteProperty -Name "FilePath" -Value "$network_share"
$row | Add-Member -MemberType NoteProperty -Name "Name" -Value "$archive"
$row | Add-Member -MemberType NoteProperty -Name "Mailbox" -Value "$user_email"
$row | Add-Member -MemberType NoteProperty -Name "IsArchive" -Value "True"
$row | Add-Member -MemberType NoteProperty -Name "TargetRootFolder" -Value "$folder"
$row | Add-Member -MemberType NoteProperty -Name "SPFileContainer" -Value ""
$row | Add-Member -MemberType NoteProperty -Name "SPManifestContainer" -Value ""
$row | Add-Member -MemberType NoteProperty -Name "SPSiteUrl" -Value ""
$csvContents += $row # append the new data to the array
}
$csvContents | Export-CSV -Path C:\temp\user.csv
$archives = Get-ChildItem $network_share
}
#generate-pst-csv
Start-Transcript -Path "C:\Software\logs\collectArchives.log"
uploadArchives
Stop-Transcript
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment