PowerShell to convert downloaded transaction file from LT Trust 401k to Quicken format

2021-10-14 / Random / 0 Comments
FYI: This assumes a 100% vesting from the employer provided funds. It lumps all the trade types together and gives a final amount. It helps get it close enough but there will be a few cents$ left over as LT Trusts export rounding is not highly accurate for some reason.
Update the file paths below to match the downloaded file location and output location.
$downloadedTransactionsFile = "C:\Users\<<NAME>>\Downloads\export.csv";
$exportedFile = "C:\Users\<<NAME>>\Desktop\import-lt.csv"


# NO TOUCH
Write-Output "Removing old cleaned file: $exportedFile"
$null = Remove-Item -Path $exportedFile -Force:$true -Confirm:$false -ErrorAction SilentlyContinue
#read downloaded csv file
$transactions = Get-Content -Path $downloadedTransactionsFile;

#convert csv into psobject
$trades = ConvertFrom-Csv $transactions;
Write-Output "Converted: $($trades.Count) items from CSV";

$buys = @();
$sells = @();
$divs = @();

#split all the trades by type
foreach ($trade in $trades) {
    if ($trade.action -eq "Buy") {
        $buys += $trade;
    }
    elseif ($trade.action -eq "Sell") {
        $sells += $trade;
    }
    elseif ($trade.action -eq "REINVDIV") {
        $divs += $trade;
    }
}
#verify counts
Write-Output "Found $($buys.Count) buy trades";
Write-Output "Found $($sells.Count) sell trades";
Write-Output "Found $($divs.Count) div trades";
Write-Output "Total trades found: $($buys.Count + $sells.Count + $divs.Count)";

#Group trades by security
$buys = $buys | Group-Object -Property Security -AsHashTable;
$sells = $sells | Group-Object -Property Security -AsHashTable;
$divs = $divs | Group-Object -Property Security -AsHashTable;

$cleanedBuys = @();
$cleanedSells = @();
$cleanedDivs = @();

$cleanedTrade = [ordered] @{
    Action   = ""
    Security = ""
    Quantity = 0
    Price    = 0
    Amount   = 0
}

Write-Output "Cleaning and preparing to export"
foreach ($buy in $buys.Keys) {
    Write-Debug "Creating: $buy buy object"
    $buyObj = New-Object psobject -Property $cleanedTrade
    $buyObj.Security = $buy
    $buyObj.Action = "Buy"
    foreach ($security in $buys[$buy]) {
        $buyObj.Quantity = ($buyObj.Quantity + ($security.Quantity -replace '[^\d.]'))
        $buyObj.Amount = ($buyObj.Amount + ($security.Amount -replace '[^\d.]'))
        $buyObj.Price = $security.Price -replace '[^\d.]'
    }
    $cleanedBuys += $buyObj
    Export-Csv -InputObject $buyObj -Path $exportedFile -NoClobber -Append -NoTypeInformation
}

foreach ($sell in $sells.Keys) {
    Write-Debug "Creating: $sell sell object"
    $sellObj = New-Object psobject -Property $cleanedTrade
    $sellObj.Security = $sell
    $sellObj.Action = "Sell"
    foreach ($security in $sells[$sell]) {
        $sellObj.Quantity = ($sellObj.Quantity + ($security.Quantity -replace '[^\d.]'))
        $sellObj.Amount = ($sellObj.Amount + ($security.Amount -replace '[^\d.]'))
        $sellObj.Price = $security.Price -replace '[^\d.]'
    }
    $cleanedSells += $sellObj
    Export-Csv -InputObject $sellObj -Path $exportedFile -NoClobber -Append -NoTypeInformation
}

foreach ($div in $divs.Keys) {
    Write-Debug "Creating: $div div object"
    $divObj = New-Object psobject -Property $cleanedTrade
    $divObj.Security = $div
    $divObj.Action = "ReinvDiv"
    foreach ($security in $divs[$div]) {
        $divObj.Quantity = ($divObj.Quantity + ($security.Quantity -replace '[^\d.]'))
        $divObj.Amount = ($divObj.Amount + ($security.Amount -replace '[^\d.]'))
        $divObj.Price = $security.Price -replace '[^\d.]'
    }
    $cleanedDivs += $divObj
    Export-Csv -InputObject $divObj -Path $exportedFile -NoClobber -Append -NoTypeInformation
}

Write-Output "Exported: $($cleanedBuys.Count) buys"
Write-Output "Exported: $($cleanedSells.Count) sells"
Write-Output "Exported: $($cleanedDivs.Count) divs"
Write-Output "Total exported: $($cleanedBuys.Count + $cleanedSells.Count + $cleanedDivs.Count) items."
Write-Output "We are now complete, file exported: $exportedFile" 
$null = Remove-Item -Path $downloadedTransactionsFile -Force:$true -Confirm:$false -ErrorAction SilentlyContinue
Read More

Remotely or locally recycle IIS application pool via PowerShell with AppPool Menu

2016-05-12 / PowerShell / 3 Comments

Save the PowerShell as Recycle-AppPool.ps1 and you can call with or without options.

Recycle-AppPool.ps1 -ServerName REMOTESERVER —– (Will run on a server remotely with current logged in creds)
Recycle-AppPool.ps1 -ServerName REMOTESERVER -WithCredentials —– (Will run on a server remotely with different credentials specified)
Recycle-AppPool.ps1 —– (Will run on locally, defaults to localhost with current logged in user)

<#
.SYNOPSIS
Recycles a selected IIS application pool 

.DESCRIPTION
Recycle-AppPools.ps1 uses a PS session to connect to a local or remote computer. It pulls down the currently configured application pools and builds a menu. 
The end user gets to select from the menu which application pool to restart. The Recycle-AppPools.ps1 then connects back to the PS Session and recycles the selected
application pool.

.PARAMETER ServerNAme 
a single computer name or leave off for localhost

.PARAMETER WithCredentials
Use this switch to specifiy credentials other than the current logged in user.

.EXAMPLE
Recycle-AppPool.ps1 -ServerName REMOTESERVER
Will run on a remote server with current logged in creds

.EXAMPLE 
Recycle-AppPool.ps1 -ServerName REMOTESERVER -WithCredentials
Will run on a server remotely with different credentials specified during launch

.EXAMPLE
Recycle-AppPool.ps1
Will run on locally. Defaults to localhost with current logged in user

.NOTES
WithCredentials is a switch, it does not accept any credentials. A prompt will appear later.
#>

Param(
   [string]$ServerName = 'localhost',
   [switch]$WithCredentials
 
) #end param
 
if (!(Test-Connection -ComputerName $ServerName -Quiet -Count 1))
{
    Write-Output "Unable to connect to $serverName"
    break
}
 
$scriptBlock = {
    Clear-Host
    Write-Output "Connected to: $env:computerName"
    if (Get-Module -ListAvailable -Name WebAdministration)
    {
        Write-Host "Loading PowerShell Web Administration..."
        Import-Module WebAdministration -ErrorAction SilentlyContinue
    }
    else
    {
        Write-Host "WebAdministration module does not exist..."
        break
    }
 
    $poolTable = @{}
    $allAppPools = Get-ChildItem IIS:\apppools
    $poolNumber = 0 
    Write-Output "Select Application Pool to Restart on server: $env:computerName"
    Write-Output ""
    foreach ($appPool in $allAppPools )
    {
        $pool = $appPool.Name
        $poolNumber += 1
        $poolTable.Add($poolNumber, $pool)
        Write-Output "$poolNumber > To restart app pool : $pool "
    }
    Write-Output ""
    $selectedPool = Read-Host "Enter # of Application Pool to Restart "
    if ($selectedPool)
    {    
        foreach ($hashValue in $poolTable.GetEnumerator())
        {  
            $key = $hashValue.Name
            $val = $hashValue.Value 
            if ($key -eq $selectedPool)
            {
                Write-Output "Restarting : $val"          
                Restart-WebAppPool $val       
            } 
        }
    }
    Write-Output "Completed reset on: $env:computerName"
    Write-Output ""
}
 
try {
     
    if ($WithCredentials)
    {
        $credentials = Get-Credential -Message "Enter credentials with administrative privilege on server"
        $session = New-PSSession -ComputerName $serverName -Credential $credentials -ErrorAction SilentlyContinue
    }
    else
    {
        $session = New-PSSession -ComputerName $serverName -ErrorAction SilentlyContinue
    }
 
    if ($session)
    {
        Invoke-Command -Session $session -ScriptBlock $scriptBlock -ErrorAction Continue
        Remove-PSSession -Session $session | Out-Null
    }
    else
    {
        Write-Output "An error has occured setting up PowerShell session (check username and password)"
    }
}
catch
{
    if ($session)
    {
        Remove-PSSession -Session $session | Out-Null
    }
    Write-Output "An error has occured setting up PowerShell session on $serverName "
}
Read More

Change Terminal Services Profile Path PowerShell

2014-10-28 / Random / 0 Comments

Problem: I needed to change all domain users to the new terminal services profile server

Solution
I was able to create a powershell script that loops through the domain and finds instances of where the terminal services profile path is set to the old server. It then replaces the old server with the new server name and logs the output to console.

You can modify the below to limit the scope of the items found (findall() only does 1000 objects by default) by changing adding in an OU filter or creating a function that adds in the user. In any case my problem was solved with the below script.

$root = "LDAP://DC=GALAXY,DC=local"
$searcher = ([ADSISearcher]"(&(samAccountType=805306368)(!userAccountControl:1.2.840.113556.1.4.803:=2))") #user account type will be person and the account not disabled.
$searcher.SearchRoot=$root
$users = $searcher.findall()
 foreach ($user in $users) {
    try {
    $userSearch = ""
    $tsprofilepath = ""
    $username = ""
    $userSearch = [adsi]"$($user.path)"
    $tsprofilepath = $userSearch.psbase.InvokeGet("TerminalServicesProfilePath")
    
    $username = $userSearch.psbase.InvokeGet("sAMAccountName")
                
       if ($tsprofilepath) { #check for not null
            if ($tsprofilepath.contains("OLDSERVERNAME")) { #check for containing string
                $newtsprofilepath = $tsprofilepath.Replace("OLDSERVERNAME", "NEWSERVERNAME") ##set ts profile path location
                Write-Output "$username has profile path of $tsprofilepath"#log existing
                $userSearch.psbase.Invokeset(“terminalservicesprofilepath”, $newtsprofilepath) #set new path
                $userSearch.setinfo() #save user info
                Write-Output "$username changed profile path to $newtsprofilepath" #log new path
                }
            else {
                Write-Output "$username has a profile path of $tsprofilepath" #log already has new path
                }
            }
            else {
                Write-Output "$username has a no profile path set" #log already has no path
            }
            #start-sleep 1 #loop sleep Timer
        }
        catch { 
        #error handle
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        Write-Output "$username had an error of: $ErrorMessage"
        Write-Output "$FailedItem"
    }
}
Read More