If you’ve ever received an error connecting to a L2TP endpoint from a Windows client, where the L2TP endpoint or Windows client is behind a NAT-T device (Or Double NAT), it is most likely due to the Windows client not supporting Internet Protocol security (IPsec) network address translation (NAT) Traversal (NAT-T) security associations to servers that are located behind a NAT device. In my specific case, I setup an L2TP connection on an Ubiquiti Edge Router ER-4 that was behind a double NAT on the WAN. On the Windows client, you would most likely receive an error similar to:
The network connection between your computer and the VPN server could net be established because the remote server is not responding. This could be because one of the network devices (e.g., firewalls, NAT, routers, etc.) between your computer and the remote server is not configured to allow VPN connections. Please contact your Administrator or your service provider to determine which devices may be causing the problem.
By default, Windows Vista and Windows Server 2008 don’t support Internet Protocol security (IPsec) network address translation (NAT) Traversal (NAT-T) security associations to servers that are located behind a NAT device. If the virtual private network (VPN) server is behind a NAT device, a Windows Vista or Windows Server 2008-based VPN client computer can’t make a Layer 2 Tunneling Protocol (L2TP)/IPsec connection to the VPN server. This scenario includes VPN servers that are running Windows Server 2008 and Windows Server 2003.
Explanation
Because of the way in which NAT devices translate network traffic, you may experience unexpected results in the following scenario:
You put a server behind a NAT device.
You use an IPsec NAT-T environment.
If you must use IPsec for communication, use public IP addresses for all servers that you can connect to from the Internet. If you must put a server behind a NAT device, and then use an IPsec NAT-T environment, you can enable communication by changing a registry value on the VPN client computer and the VPN server.
Resolution
To create and configure the AssumeUDPEncapsulationContextOnSendRule registry value, follow these steps:
Log on to the Windows Vista client computer as a user who is a member of the Administrators group.
Select Start > All Programs > Accessories > Run, type regedit, and then select OK. If the User Account Control dialog box is displayed on the screen and prompts you to elevate your administrator token, select Continue.
On the Edit menu, point to New, and then select DWORD (32-bit) Value.
Type AssumeUDPEncapsulationContextOnSendRule, and then press ENTER.
Right-click AssumeUDPEncapsulationContextOnSendRule, and then select Modify.
In the Value Data box, type one of the following values:
0It’s the default value. When it’s set to 0, Windows can’t establish security associations with servers located behind NAT devices.
1When it’s set to 1, Windows can establish security associations with servers that are located behind NAT devices.
2When it’s set to 2, Windows can establish security associations when both the server and VPN client computer (Windows Vista or Windows Server 2008-based) are behind NAT devices.
In 365, you can use Compliance Searches to search and/or remove emails across all of your user’s mailboxes. Compliance searches have replaced the Search-Mailbox cmdlet, which has been deprecated as of April 2020.
Pre-Requisites
You must be a member of the Discovery Management role group or be assigned the Compliance Search management role. Here’s how you can add a user to the Discovery Management group and confirm membership
#Connect to Security and Compliance Center
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking
#Add User to Discovery Management Group (Replace John Doe with your user)
Add-RoleGroupMember -Identity "Discovery Management" -Member "John Doe"
#Confirm Membership
Get-RoleGroupMember -Identity "Discovery Management"
#Disconnect Session
Remove-PSSession $Session
Function to Search & Remove Spam/Phishing Emails From All Mailboxes
Modify the Search Variables below to suite your needs
Function RemoveMaliciousEmails()
{
#MODIFY THE BELOW VARIABLES - YOU MUST USE THEM ALL AND OPTIONALLY LEAVE SUBJECT BLANK!!!
$compSearchName = "MaliciousEmail_$(Get-Date -Format "MMddyyyy_HHmm")"
$compStartDate = "2020-02-24" #YYYY-MM-DD
$compEndDate = "2020-02-25" #Must be different than Start Date, if searching "today" make this date tomorrow
$compFrom = "hacker@phishing.com" #You can use just the domain for a wildcard sender BUT USE WITH CAUTION
$compSubject = "Phishing Test" #Use backtick ` to escape special characters in the subject such as a quote ex: Dave shared `"New File`" with you
#
#DO NOT MODIFY ANYTHING BELOW HERE
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking
Write-Host "NAME: $($compSearchName)"
Write-Host "START: $($compStartDate)"
Write-Host "END: $($compEndDate)"
Write-Host "FROM: $($compFrom)"
Write-Host "SUBJECT: $($compSubject)"
If ($compSubject.Trim() -eq "")
{
$ncs = New-ComplianceSearch -Name $compSearchName -ExchangeLocation all -ContentMatchQuery "(c:c)(received=$compStartDate..$compEndDate)(from=$compFrom)"
}
Else
{
$ncs = New-ComplianceSearch -Name $compSearchName -ExchangeLocation all -ContentMatchQuery "(c:c)(received=$compStartDate..$compEndDate)(from=$compFrom)(subject=`"$compSubject`")"
}
Write-Host "[$(Get-Date -Format G)] Start Compliance Search: $($compSearchName)"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Searching"
Start-ComplianceSearch -Identity $compSearchName
$resultSearch = Get-ComplianceSearch -Identity $compSearchName
While ($resultSearch.Status -ne "Completed")
{
$resultSearch = Get-ComplianceSearch -Identity $compSearchName
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
If (($resultSearch.Items -le 0) -OR ([string]::IsNullOrWhiteSpace($resultSearch.SuccessResults)))
{
Write-Host "`n[$(Get-Date -Format G)] Search completed with 0 successful results, Invalid Search Quitting!" -ForegroundColor Red
Remove-PSSession $Session
Return
}
Elseif ($resultSearch.Items -ge 500)
{
Write-Host "`n[$(Get-Date -Format G)] Search Completed with $($resultSearch.Items) successful results, you will need to run mulitple times!" -ForegroundColor Yellow
}
Else
{
Write-Host "`n[$(Get-Date -Format G)] Search Completed with $($resultSearch.Items) successful results"
}
Write-Host "[$(Get-Date -Format G)] Create Preview and Export of Results"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Processing"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Preview
$resultPreview = Get-ComplianceSearchAction -Identity "$($compSearchName)_Preview"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Export -ExchangeArchiveFormat SinglePst -Format FxStream
$resultExport = Get-ComplianceSearchAction -Identity "$($compSearchName)_Export"
While ($resultPreview.Status -ne "Completed" -AND $resultExport.Status -ne "Completed")
{
$resultPreview = Get-ComplianceSearchAction -Identity "$($compSearchName)_Preview"
$resultExport = Get-ComplianceSearchAction -Identity "$($compSearchName)_Export"
#Write-Host "[$(Get-Date -Format G)] Processing..."
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
Write-Host "`n[$(Get-Date -Format G)] Preview and Export successfully created"
Write-Host "[$(Get-Date -Format G)] View Results at https://protection.office.com/"
Write-Host "[$(Get-Date -Format G)] Preview: Search -> Content Search -> Searches tab -> $($compSearchName)"
Write-Host "[$(Get-Date -Format G)] Export: Search -> Content Search -> Exports tab -> $($compSearchName)_Export"
Write-Host "[$(Get-Date -Format G)] Start Purging emails"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Purging"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Purge -PurgeType HardDelete -Confirm:$False
$resultPurge = Get-ComplianceSearchAction -Identity "$($compSearchName)_Purge"
While ($resultPurge.Status -ne "Completed")
{
$resultPurge = Get-ComplianceSearchAction -Identity "$($compSearchName)_Purge"
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
Write-Host "`n[$(Get-Date -Format G)] Purge complete"
$confirmDelete = Read-Host "Delete Compliance Search, Preview, Export, and Purge? [Y/N]"
If ($confirmDelete -eq 'Y')
{
Write-Host "[$(Get-Date -Format G)] Deleting Compliance Search, Preview, Export, and Purge..."
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Preview" -Confirm:$False
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Export" -Confirm:$False
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Purge" -Confirm:$False
Remove-ComplianceSearch -Identity $compSearchName -Confirm:$False
}
Write-Host "[$(Get-Date -Format G)] Removing Powershell Session..."
Remove-PSSession $Session
}
RemoveMaliciousEmails
Write-Out Function to Output Multiple Colors on a Single Line
#Requires -Version 4.0
Function Write-Out
{
<#
.SYNOPSIS
Write output to console and/or log file. Supports multiple foreground and background colors on a single line and
advanced options to insert lines, spaces, or tabs before or after the text as well as timestamps.
.DESCRIPTION
Uses Write-Host to output color text to the console, and supports using multiple foreground and background colors
on a single line. Uses Set-Content and Add-Content to output to a file.
It works by accepting strings as an array and then you can assign the foreground or background colors by passing
them as arrays for the matching text. It also accepts Default which allows you skip specifying a color and use the
default.
This function requires Powershell 4.0 to support the alias attribute in the function.
.PARAMETER Text
Optional. Array of strings to write to console/log. If you do not need to use multiple colors on a single line you can pass a single string instead of an array of strings. Otherwise, if you need to multiple colors on a single line pass an array of strings and associated colors using -ForegroundColor, -BackgroundColor, -ForegroundColorDefault, or -BackgroundColorDefault.
.PARAMETER ForegroundColor
Optional. Array of foreground Colors to write to console. Default means the ForegroundColorDefault value is used.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER ForegroundColorDefault
Optional. Default foreground color to write to console. Default is set to white.
Valid Colors: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER BackgroundColor
Optional. Array of background colors to write to console. Default means the BackgroundColorDefault value is used.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER BackgroundColorDefault
Optional. Default background color to write to console. Default is none.
Valid Colors: Default, Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
.PARAMETER PreLine
Optional. Add blank lines before your text. Default is 0.
.PARAMETER PreSpace
Optional. Add spaces before your text. Default is 0.
.PARAMETER PreTab
Optional. Add Tabs before your text. Default is 0.
.PARAMETER TimeStampFormat
Optional. Format used for time stamps. Default is 'yyyy-MM-dd HH:mm:ss'
.PARAMETER TimeStamp
Optional. Adds time stamp in square brackets before your text.
.PARAMETER ClearHost
Optional. Clear the console before your text.
.PARAMETER PostLine
Optional. Add blank lines after your text. Default is 0.
.PARAMETER PostSpace
Optional. Add spaces after your text. Default is 0.
.PARAMETER PostTab
Optional. Add tabs after your text. Default is 0.
.PARAMETER NoNewLine
Optional. Do not add a new line after your text and optional post text options. Default is to add a new line.
.PARAMETER LogFile
Optional. Absolute or relative path of the log file.
.PARAMETER Overwrite
Optional. Ovewrite the log file. Default is to append to the log file.
.INPUTS
Parameters above
.OUTPUTS
None
.NOTES
Author: Brian Steinmeyer
URL: http://sigkillit.com/
Created: 4/18/2020
Version 1.3
- Added LogOnly Option for only writing text to a log file
Version 1.2
- Set Text, ForegroundColor, and BackgroundColor to default value of @() to fix errors checking counts in some circumstances
- Fixed an issue where ForegroundColorDefault and BackgroundColorDefault were not working properly in some circumstances
- Added Requires -Version 4.0
Version 1.1
- Completely rewrote the "Main Text" section
- Added "Default" as a color option, which allows you to use the default values for foreground/background
- Useful when you want to specify a backgroundcolor in certain parts of a line like the middle
- Ex: Write-Out -Text "How to ","highlight ","the middle text" -BackgroundColor Default,Yellow,Default
Version: 1.0
- Initial Creation inspired by PSWriteColor (https://github.com/EvotecIT/PSWriteColor)
- Improved upon by switching Foreground and Background Colors to default values if colors are not specifid for all strings.
Will also ignore extra colors if more colors are specified than strings specified.
.EXAMPLE
Write-Out -Text "Start with Red Text ","Then Switch to Blue Text ","Now Magenta" -ForegroundColor Red,Blue,Magenta
.EXAMPLE
Write-Out -Text "White on Black ","Black on White ","Dark Cyan on Cyan ","Yellow on Green ","Default Color" -ForegroundColor White,Black,DarkCyan,Yellow -BackgroundColor Black,White,Cyan,Green
.EXAMPLE
Write-Out -Text "Make this"," entire line"," the same color by setting defaults" -ForegroundColorDefault Yellow -BackgroundColorDefault Magenta
.EXAMPLE
Write-Out -Text "Add a blank line and two tabs ","before ","my text" -ForegroundColor Green,Cyan,White -PreLine 1 -PreTab 2
.EXAMPLE
Write-Out -Text "Add two blank ","lines ","after my text" -ForegroundColor White,Green,White -PostLine 2
.EXAMPLE
Write-Out -Text "Add 3 spaces before my text" -ForegroundColor Gray -Prespace 3
.EXAMPLE
Write-Out -Text "White text and a tab after" -ForegroundColor White -NoNewLine -PostTab 1
Write-Out -Text "Black text on Yellow ","and then back to white" -ForegroundColor Black,White -BackgroundColor Yellow
.EXAMPLE
Write-Out -Text "An easy way to ","highlight ","text in the middle" -BackgroundColor Default,Yellow
.EXAMPLE
Write-Out -Text "You can even add a ","time stamp ","before your output" -ForegroundColor White,Green,White -TimeStamp -PreLine 3
.EXAMPLE
Write-Out -Text "You can change the ","time stamp format" -ForegroundColor White,Yellow -TimeStamp -TimeStampFormat "dd-MM-yyy HH:mm" -PreLine 1 -PostLine 1
.EXAMPLE
Write-Out -Text "An"," Error"," occurred let's write overwrite/create a new log file" -ForegroundColor White,Red,White -TimeStamp -LogFile "script.log" -Overwrite
.EXAMPLE
Write-Out -Text "Now you can ","Append ","this line to your log file" -ForegroundColor Cyan,Magenta -TimeStamp -LogFile "script.log"
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$false)]
[AllowEmptyString()]
[alias ('T')]
[String[]]
$Text = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('FGC', 'FC')]
[string[]]
$ForegroundColor = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('FGCD', 'FCD')]
[string]
$ForegroundColorDefault = [ConsoleColor]::White,
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('BGC', 'BC')]
[String[]]
$BackgroundColor = @(),
[Parameter(Mandatory=$false)]
[ValidateSet("Default","Black","DarkBlue","DarkGreen","DarkCyan","DarkRed","DarkMagenta","DarkYellow","Gray","DarkGray","Blue","Green","Cyan","Red","Magenta","Yellow","White")]
[alias ('BGCD', 'BCD')]
[string]
$BackgroundColorDefault = "Default",
[Parameter(Mandatory=$false)]
[int]
$PreLine = 0,
[Parameter(Mandatory=$false)]
[int]
$PreSpace = 0,
[Parameter(Mandatory=$false)]
[int]
$PreTab = 0,
[Parameter(Mandatory=$false)]
[Alias('TSF', 'TS')]
[string]
$TimeStampFormat = 'yyyy-MM-dd HH:mm:ss',
[Parameter(Mandatory=$false)]
[switch]
$TimeStamp,
[Parameter(Mandatory=$false)]
[switch]
$ClearHost,
[Parameter(Mandatory=$false)]
[int]
$PostLine = 0,
[Parameter(Mandatory=$false)]
[int]
$PostSpace = 0,
[Parameter(Mandatory=$false)]
[int]
$PostTab = 0,
[Parameter(Mandatory=$false)]
[switch]
$NoNewLine = $false,
[Parameter(Mandatory=$false)]
[alias ('Log', 'L')]
[string]
$LogFile = '',
[Parameter(Mandatory=$false)]
[switch]
$LogOnly = $false,
[Parameter(Mandatory=$false)]
[switch]
$Overwrite = $false
)
Begin
{
#Nothing to Do Here
}
Process
{
#Optional - Do Not Write to ConsoleColor
If (!($LogOnly))
{
#Optional - Prefix Text
If ($ClearHost) { Clear-Host }
If ($PreLine -gt 0) { For ($i = 0; $i -lt $PreLine; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line(s) before Main text
If ($PreSpace -gt 0) { For ($i = 0; $i -lt $PreSpace; $i++) { Write-Host -Object " " -NoNewLine } } # Add Tab(s) before Main text
If ($PreTab -gt 0) { For ($i = 0; $i -lt $PreTab; $i++) { Write-Host -Object "`t" -NoNewLine } } # Add Space(s) before Main text
If ($TimeStamp) { Write-Host -Object "[$([datetime]::Now.ToString($TimeStampFormat))]" -NoNewline } # Add Timestamp before Main Text
#MAIN TEXT
If (($Text.Count -gt 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -eq 0))
{
#Text Only Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -gt 0) -AND ($BackgroundColor.Count -eq 0))
{
#Text and ForegroundColor Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($ForegroundColor.Count -le $i) { $ForegroundColor += $ForegroundColorDefault } #ForegroundColor Not Specified Set to Default
If ($ForegroundColor[$i] -eq "Default") { $ForegroundColor[$i] = $ForegroundColorDefault }
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -gt 0))
{
#Text and BackgroundColor Specified
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($BackgroundColor.Count -le $i) { $BackgroundColor += $BackgroundColorDefault } #BackgroundColor Not Specified Set to Default
If ($BackgroundColor[$i] -eq "Default")
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColorDefault -BackgroundColor $BackgroundColor[$i] -NoNewLine
}
}
}
ElseIf (($Text.Count -gt 0) -AND ($ForegroundColor.Count -gt 0) -AND ($BackgroundColor.Count -gt 0))
{
#Text, ForegroundColor, and BackgroundColor Specified (FAILS NOT WRITING DEFAULT)
For ($i = 0; $i -lt $Text.Count; $i++)
{
If ($ForegroundColor.Count -le $i) { $ForegroundColor += $ForegroundColorDefault } #ForegroundColor Not Specified Set to Default
If ($BackgroundColor.Count -le $i) { $BackgroundColor += $BackgroundColorDefault } #BackgroundColor Not Specified Set to Default
If ($ForegroundColor[$i] -eq "Default") { $ForegroundColor[$i] = $ForegroundColorDefault }
If ($BackgroundColor[$i] -eq "Default")
{
If ($BackgroundColorDefault -eq "Default")
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -NoNewLine
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColorDefault -NoNewLine
}
}
Else
{
Write-Host $Text[$i] -ForegroundColor $ForegroundColor[$i] -BackgroundColor $BackgroundColor[$i] -NoNewLine
}
}
}
Else
{
#No Text, ForegroundColor, or BackgroundColor Specified ($Text.Count -eq 0) -AND ($ForegroundColor.Count -eq 0) -AND ($BackgroundColor.Count -eq 0)
}
#Post Text
If ($PostSpace -gt 0) { for ($i = 0; $i -lt $PostSpace; $i++) { Write-Host -Object " " -NoNewLine } } # Add Tab(s) after Main text
If ($PostTab -gt 0) { for ($i = 0; $i -lt $PostTab; $i++) { Write-Host -Object "`t" -NoNewLine } } # Add Space(s) after Main text
If ($PostLine -gt 0) { for ($i = 0; $i -lt $PostLine; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line(s) after Main text
If ($NoNewLine) { Write-Host -NoNewline } else { Write-Host } # Add New Line after Main Text Unless NoNewLine is Supplied
}
#Log File
$TextToWrite = "" #Build Text to Write to Log File
If ($PreLine -gt 0) { For ($i = 0; $i -lt $PreLine; $i++) { $TextToWrite += "`n" } } # Add empty line(s) before Main text
If ($PreSpace -gt 0) { For ($i = 0; $i -lt $PreSpace; $i++) { $TextToWrite += " " } } # Add Tab(s) before Main text
If ($PreTab -gt 0) { For ($i = 0; $i -lt $PreTab; $i++) { $TextToWrite += "`t" } } # Add Space(s) before Main text
If ($TimeStamp) { $TextToWrite += "[$([datetime]::Now.ToString($TimeStampFormat))]" } # Add Timestamp before Main Text
If ($Text.Count -gt 0) { For ($i = 0; $i -lt $Text.Count; $i++) { $TextToWrite += $Text[$i] } } #Add Main Text
If ($PostSpace -gt 0) { for ($i = 0; $i -lt $PostSpace; $i++) { $TextToWrite += " " } } # Add Tab(s) after Main text
If ($PostTab -gt 0) { for ($i = 0; $i -lt $PostTab; $i++) { $TextToWrite += "`t" } } # Add Space(s) after Main text
If ($PostLine -gt 0) { for ($i = 0; $i -lt $PostLine; $i++) { $TextToWrite += "`n" } } # Add empty line(s) after Main text
If ($LogFile -eq "")
{
#No LogFile Specified - Skip
}
ElseIf(!(Test-Path -Path $LogFile))
{
#Create Log File If Does Not Exist
If ($NoNewLine)
{
$nf = New-Item -Path $LogFile -type file -force -Value $TextToWrite
}
Else
{
$nf = New-Item -Path $LogFile -type file -force -Value $TextToWrite`r`n
}
}
Else
{
#Log File Exists
If($Overwrite)
{
#Overwrite Log File
If ($NoNewLine)
{
Set-Content -Path $LogFile -Value $TextToWrite -NoNewline
}
Else
{
Set-Content -Path $LogFile -Value $TextToWrite
}
}
Else
{
#Append Log File
Try {
If ($NoNewLine)
{
Add-Content -Path $LogFile -Value $TextToWrite -ErrorAction Stop -NoNewline
}
Else
{
Add-Content -Path $LogFile -Value $TextToWrite -ErrorAction Stop
}
} Catch {
Start-Sleep -s 3
If ($NoNewLine)
{
Add-Content -Path $LogFile -Value $TextToWrite -NoNewline
}
Else
{
Add-Content -Path $LogFile -Value $TextToWrite
}
}
}
}
}
End
{
#Nothing to Do Here
}
}