PowerShell Scriptlets to check if NLA is enabled for Remote Desktop

Scenario: You want to see if  NLA (Network Level Authentication) is enabled on all of your servers for Remote Desktop.

The PowerShell code below is not a .ps1, although you can make a .ps1 out of it if you would like.  I like to teach working  “within” PowerShell, not just being a script monkey.

In order to run the code, you will need to open Powershell OR Powershell ISE with an account with elevated permissions to access your servers (Run-AS).  The purpose of working within PowerShell is so that you can  reuse/recycle the code below to do other things too.
Once PowerShell is opened, follow the steps:
  1. Build your $Servers Variable — Select a method to populate $Servers
  2. Run the Query to build the $Results table
  3. Display the $Results — Select a method

 

 

#1. Build your $Servers Variable — Select one of the methods below to populate $Servers

  $Servers = “ExSrv1″,”ExSrv2”   #Feel free to list the servers by name

    #-or-
        $Servers = Import-csv C:tempservers.csv | Select -expandproperty Name   #Create a CSV with a NAME column header

    #-or-
        $Servers =  get-adcomputer -searchbase “OU=Servers,DC=steve,DC=com” -properties Name -Filter *|  Select -ExpandProperty Name  #Pull a list of AD Computers via AD PowerShell

#2. Run the query to build the $Results variable 

$Results = @()
$Servers | %{
    #Collect NLA Data
    $name = $_
    $NLA = Get-WmiObject -class “Win32_TSGeneralSetting” -Namespace rootcimv2terminalservices -ComputerName $name -Filter “TerminalName=’RDP-tcp'” | Select -ExpandProperty UserAuthenticationRequired
   
    #Display in PowerShell Screen
    “$name : NLA_Enabled:$(If($NLA -eq 1){“Yes”}else{“No”})”

    #Add the data to the $results variable
    $ServerObj = New-Object PSObject
    $ServerObj | Add-Member NoteProperty -Name “Server” -value $name
    $ServerObj | Add-Member NoteProperty -Name “NLA_Enabled” -value $(If($NLA -eq 1){“Yes”}else{“No”})
    $Results += $ServerObj
   
    #Reset Variable
    $Name = $null
    $NLA = 0
}

#3. Display the $Results –  Select a method

$Results

    #-or Export the Results –
        $Results | Export-CSV C:tempresults.csv

    #-or Email the Results –
        $Header = @”
        <style>
        TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
        TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
        TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black; text-align: center;}
        tr:nth-child(odd) { background-color:#F2F2F2;}
        tr:nth-child(even) { background-color:white;}
        </style>
“@
        $body =”$($results | ConvertTo-Html -Head $header)”
        $smtp = “smtp.steve.com”
        $to = “steve@steve.com”
        $from = “SteveDoingSomething@steve.com”
        $subject = “Results of NLA”
        send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high

EWS Script: Perform a RegEx search against all Items in a Mailbox and perform an action

Scenario:  Although RegEx searches are not supported within the Exchange toolset, here is an EWS Script that will perform two kinds of RegEx searches; Patterns AND exact matches (not case sensitive).

The script below is going to do the following:

  • If the mailbox item matches the RegEx, it will move the email item into a folder: BadFolder_Reg
  • If the mailbox item matches the Term, it will move the email item into a folder: BadFolder_Term
  • If any mailbox item has an attachment, it will download it into a directory

Scripts:

#Finding items With RegEx
#Variables
$cred = Get-credential  #credentials will fullaccess to access the mailbox
$mailboxname = “stevetest25@domain.com”  #The Mailbox you wish to perform the query and restore on
$EWS_DLL = “C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll”
$EWS_URL = “https://domain/ews/exchange.asmx&#8221;

#Configure connection to EWS
Import-Module -Name $EWS_DLL
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2013)
$service.Url = new-object System.Uri($EWS_URL)
$service.UseDefaultCredentials = $false
$service.Credentials = $cred.GetNetworkCredential()

 

#Find all Mailbox folders
$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)

#Bind to BadFolders for RegEx and Terms
$BADfolder_Reg = $findFolderResults | Where displayname -like “BadFolder_Reg”
$BADfolder_Term = $findFolderResults | Where displayname -like “BadFolder_Term”

If($BadFolder_Reg -eq $null){
#Create a Folder called BAD on the Root
“Bad folder doesnt exist, creating it now”
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailboxname)
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = “BadFolder_reg”
$NewFolder.Save($Folder.id)

$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
#Find all folders in the mailbox
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)
$BADfolder_Reg = $findFolderResults | Where displayname -like “BadFolder_Reg”
}

If($BadFolder_Term -eq $null){
#Create a Folder called BAD on the Root
“Bad folder doesnt exist, creating it now”
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailboxname)
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = “BadFolder_Term”
$NewFolder.Save($Folder.id)

$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
#Find all folders in the mailbox
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)
$BADfolder_Term = $findFolderResults | Where displayname -like “BadFolder_Term”
}

#Create Variables for Search

$ItemPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$i = 0
$i_end = $findfolderResults.item.count
$reg = @()

$reg +=  “[1-9][0-9]{2}-[0-9]{2}-[0-9]{4}^d”

$reg += “(^|D)(d{3}-d{2}-d{4})(D|$)”

$DownloadDirectory = “\servershare$attachments”
$term = ” test123 “,” steve “,” batman “,” superman ”

#Loop each mail folder and perform the search
Do{
If(($findFolderResults.Folders[$i]).DisplayName -notlike “Badfolder*”){

“Checking Folder: $(($findFolderResults.Folders[$i]).DisplayName)”
$ItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)

Do{
$AqsString = “System.Message.DateReceived:01/01/2000..12/31/2099”
$fiItems = $findFolderResults.Folders[$i].FindItems($AqsString,$ItemView)
$ItemView.offset += $fiItems.Items.Count
[Void]$service.LoadPropertiesForItems($fiItems , $ItemPropset)

foreach($Item in $fiItems.Items){
“Checking on $($Item.Subject)”
#Check for attachments#########################
If($item.Hasattachments -eq $true){
“Attachment Detected on $($Item.Subject)”
foreach($attach in $Item.Attachments){
$attach.Load()
$fiFile = new-object System.IO.FileStream(($downloadDirectory + “” + $attach.Name.ToString()), [System.IO.FileMode]::Create)
$fiFile.Write($attach.Content, 0, $attach.Content.Length)
$fiFile.Close()
write-host “Downloaded Attachment : ” + (($downloadDirectory + “” + $attach.Name.ToString()))
}
}
#^Check for attachments#########################

#Check for Reg#########################
$reg_result = $false
$b_temp = $Item.body.text
#Loop regex
$reg | %{
$r = $b_temp -match “$_”
“Result: $r”
if($r -eq $true){“Setting $reg_result to $r”;$reg_result = $true}
}

#display
“$Reg_result – The MSG with Subject: $($Item.subject) ”

If($reg_result -eq $true){
“Moving $($Item.Subject) to BadFolder_reg”
[VOID]$Item.Move($BadFolder_reg.Id)}
#^Check for Reg##################################################

#Check for Terms#########################
$Term_result = $false
$b_temp = $Item.body.text
#Loop term
$term | %{

$rr = $b_temp -match $_
“Result: $rr”
if($rr -eq $true){“Setting $term_result to $rr”;$term_result = $true}
$term_temp = $null
}

#display
“$term_result – The MSG with Subject: $($Item.subject) ”

If($term_result -eq $true){
“Moving $($Item.Subject) to BadFolder_term”
[VOID]$Item.Move($BadFolder_term.Id)}
#^Check for Terms##################################################

#clean var
$r = $null
$b_temp = $null

}
}While($fiItems.moreavailable -eq $true)
}

$i++
“FolderID Counter $i”

}While ($i -le $i_end)

 

 

Exchange PowerShell: Export a mailbox into multiple psts by size using native Exchange commands

Scenario:  Using native Exchange PowerShell commands, export a single mailbox into multiple 10GB PSTs (or another size). This is to mimic the eDiscovery tool in which it makes multiple PST’s that stay around 10GB each.

The script/commands below will perform a search mailbox until it hits the 10000 item limit.  When it hits the 10,000 item limit, it finds the previous  date where the search results is under the 10,000 item limit and records it.  Then the script will take all the dates it records and add the size until it hits around 10GB.  It records those dates in a array and then exports to a PST.

Script:

#Initialize Variables###########################################
$mbx = “Steve”
$stat = Get-mailboxstatistics $mbx | Select DisplayName,TotalDeletedItemSize, TotalItemSize,ItemCount
$TotalSize = [int]$stat.TotalItemSize.Value.ToMB() + [int]$stat.TotalDeletedItemSize.Value.ToMB()
$SizeforPST = [int]10240 ; “$MBX : Total Size $totalSize MB”
$CutThePST = “Yes”
$PSTFilePath =”\ExSvr1PSTFILES”
###############################################################

#If MBX totalsize is greater than $SizeforPST ###############################################################
If($TotalSize -gt $SizeforPST){

“Entering If Statement:  TotalSize ($TotalSize) is greater than $SizeForPST”

#Find Oldest Item in Mailbox to know when to stop searching
$OldestItem = Get-MailboxFolderStatistics $mbx -IncludeOldestAndNewestItems | Where OldestItemReceivedDate -ne $Null | Sort OldestItemReceivedDate | Select -ExpandProperty OldestItemReceivedDate -first 1
$oldestItem = $oldestItem.AddMonths(-1)  #Subtract a month to ensure that search goes before oldest item.
$OldestItem = $OldestItem.ToSTring((“M/d/yyyy”))
#Set Start and End Month 1 Month Apart
$end = get-date -Format “M/d/yyyy”
$start = [datetime]$end
$start= $start.AddMonths(-1)
$start = $start.ToString((“M/d/yyyy”))

#Initialize $results Variable and Final variable
$Results = Search-Mailbox $mbx -SearchDumpster -SearchQuery “Received:$start..$End” –estimateresultonly | Select ResultItemsCount,@{n=’Size’;e={([Microsoft.Exchange.Data.ByteQuantifiedSize]$_.ResultItemsSize).ToMb()}}
$final = @()

#Loop It –
Do{
If($results.ResultItemsCount -ge 10000){
Do{
$start= [datetime]$start
$start= $start.AddDays(5)
$start = $start.ToString((“M/d/yyyy”))
$Results = Search-Mailbox $mbx -SearchDumpster -SearchQuery “Received:$start..$End” –estimateresultonly | Select ResultItemsCount,@{n=’Size’;e={([Microsoft.Exchange.Data.ByteQuantifiedSize]$_.ResultItemsSize).ToMb()}}
“ResultCount: $results.ResultItemsCount between $start – $end”
}While($Results.ResultItemsCount -ge 10000)
}

If($Results.ResultItemsCount -lt 10000){
Do{
If([datetime]$Start -lt [datetime]$oldestitem){Break}
$start= [datetime]$start
$start= $start.AddMonths(-1)
$start = $start.ToString((“M/d/yyyy”))
$Results = Search-Mailbox $mbx -SearchDumpster -SearchQuery “Received:$start..$End” –estimateresultonly | Select ResultItemsCount,@{n=’Size’;e={([Microsoft.Exchange.Data.ByteQuantifiedSize]$_.ResultItemsSize).ToMb()}}
“ResultCount: $results.ResultItemsCount between $start – $end”
}While($Results.ResultItemsCount -lt 10000)

#Since ResultItemCount just became greater than or equal too 10000, subtract add a month to start.
$start= [datetime]$start
$start= $start.AddMonths(1)
$start = $start.ToString((“M/d/yyyy”))
$Results = Search-Mailbox $mbx -SearchDumpster -SearchQuery “Received:$start..$End” –estimateresultonly | Select ResultItemsCount,@{n=’Size’;e={([Microsoft.Exchange.Data.ByteQuantifiedSize]$_.ResultItemsSize).ToMb()}}

}

“Result Count: $($results.ResultItemsCount) Size $($results.size)”

#Build the Array
$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “Alias” -Value $mbx
$ServerObj | Add-Member NoteProperty -Name “Start” -Value $start
$ServerObj | Add-Member NoteProperty -Name “End” -Value $end
$ServerObj | Add-Member NoteProperty -Name “ItemCount” -Value $results.ResultItemsCount
$ServerObj | Add-Member NoteProperty -Name “Size” -Value $results.Size
$Final += $ServerObj

#Recalibrate Variables
$end = $start
$start = [datetime]$end
$start= $start.AddMonths(-1)
$start = $start.ToString((“M/d/yyyy”))
$Results = Search-Mailbox $mbx -SearchDumpster -SearchQuery “Received:$start..$End” –estimateresultonly | Select ResultItemsCount,@{n=’Size’;e={([Microsoft.Exchange.Data.ByteQuantifiedSize]$_.ResultItemsSize).ToMb()}}

“While Start: $start > OldestItem: $oldestitem”
}While([datetime]$start -ge [datetime]$OldestItem)

$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “Alias” -Value $mbx
$ServerObj | Add-Member NoteProperty -Name “Start” -Value $start
$ServerObj | Add-Member NoteProperty -Name “End” -Value $end
$ServerObj | Add-Member NoteProperty -Name “ItemCount” -Value $results.ResultItemsCount
$ServerObj | Add-Member NoteProperty -Name “Size” -Value $results.Size
$Final += $ServerObj
###########################################################################################################

#Create a PST Hash Table

$PST_Final = @()
$PSTSize = 999999

$Final | %{
“____________________________________”
“Starting Loop”

if($PSTSize -eq 999999){

$PSTSize = $_.Size
$PST_end = $_.End
$PST_Start = $_.Start
“1st Loop: $PST_Start — $PST_end — $PSTSize”

}else{

“Entering Else Loop”
$PST_Start_temp = $_.start
$PST_End_temp = $_.end

#When on second pass, add the two sizes together
$PSTSize_temp = $PSTSize + $_.Size
Write-host “PST Size = $PSTSize_Temp” -ForegroundColor Cyan

If($PSTSize_temp -lt $SizeForPST){
“..Less than $SizeForPST  ($PSTSize_Temp)”
$PSTSize = $PSTSize_Temp
$PST_Start = $PST_Start_Temp

“….New DateRange:  $PST_Start — $PST_END”

}

If($PSTSize_Temp -gt $SizeForPST){
“..Greater Than $SizeForPST ($PSTSize_temp)”
$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “Alias” -Value $mbx
$ServerObj | Add-Member NoteProperty -Name “Start” -Value $PST_Start
$ServerObj | Add-Member NoteProperty -Name “End” -Value $PST_End
$ServerObj | Add-Member NoteProperty -Name “Size” -Value $PSTSize
$PST_Final += $ServerObj

$PST_END = $PST_Start
$PSTSize = [int]0

}

}

}

$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “Alias” -Value $mbx
#$ServerObj | Add-Member NoteProperty -Name “Start” -Value $PST_Start
$ServerObj | Add-Member NoteProperty -Name “Start” -Value “1/1/1900”
$ServerObj | Add-Member NoteProperty -Name “End” -Value $PST_End
$ServerObj | Add-Member NoteProperty -Name “Size” -Value $PSTSize
$PST_Final += $ServerObj

$PST_FINAL

}

If($PST_Final -eq $null){
$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “Alias” -Value $mbx
#$ServerObj | Add-Member NoteProperty -Name “Start” -Value $PST_Start
$ServerObj | Add-Member NoteProperty -Name “Start” -Value “1/1/1900”
$ServerObj | Add-Member NoteProperty -Name “End” -Value $(get-date -Format “M/d/yyyy”)
$ServerObj | Add-Member NoteProperty -Name “Size” -Value $TotalSize
$PST_Final += $ServerObj

}

#Export the PST for this user
If($CutThePST -eq “Yes”){

$PST_Final | %{
$N = $_.Alias
$S = $_.Start
$E = $_.End
$PSTName = $N+”_”+$S+”_”+$E
$PSTName = $PSTName -replace (“/”,”-“)
$F = “$PSTFilePath$PstName.pst”
New-mailboxExportRequest -mailbox $N -contentfilter {(Received -ge $s) -and (Received -le $e)} -name $PSTName -filepath $F -baditemlimit 1000000 -acceptlargedataloss
}
}