Restart Event IDs

I can never remember what these Event IDs are, so it's time to record them here.

Event IDDescription
1074Logged when an app (ex: Windows Update) causes the system to restart, or when a user initiates a restart or shutdown.
6006Logged when an app (ex: Windows Update) causes the system to restart, or when a user initiates a restart or shutdown.
6008Logged as a dirty shutdown. It gives the message "The previous system shutdown at time on date was unexpected".

Here's an article elaborating on this:




PS2.0:

Get-WmiObject win32_operatingsystem | select csname, @{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}

PS3.0

Get-CimInstance -ClassName win32_operatingsystem | select csname, lastbootuptime


EWS & PowerShell

A bit of stuff using the EWS managed API, which can be downloaded here:
http://www.microsoft.com/en-us/download/details.aspx?id=35371

Note: Make sure the path to the EWS dll matches the install location of the EWS managed API. Change it if necessary.

This script searches folders in mailboxes under the Contacts folder, looking for 'Skype for Business contacts' and then deletes it. It is also doing a disable-ummailbox. As both actions are quite destructive, there's a warning for the person running the script.

The list of mailboxes to run this against was gathered with a get-aduser searchbase of specific OUs, extracting the Primary SMTP address and outputting that to a text file.


$inputfile = "mailboxlist.txt"

$MailboxList = get-content $inputfile
$MailboxListcount = $MailboxList.count

$CurrentDate = (Get-Date).ToString('MMM-dd-yyyy')

[string]$logfilepath = "SkypeForBus-DeletionsLog_" + $CurrentDate + ".csv"

Write-host -backgroundcolor yellow -foregroundcolor red "WARNING! This script will perform the following:"`n
write-host "Using the file $inputfile containing $MailboxListcount users"`n
write-host "Action 1: Disable-UMMailbox -Identity `$MailboxName -KeepProperties:`$True -Confirm:`$false"
write-host "Action 2: Delete the Skype for Business contacts folder (if found) under the Contacts folder"`n

$verify = Read-Host "If you wish to proceed, type Y"

if($verify -eq "Y"){

$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"
    [void][Reflection.Assembly]::LoadFile($dllpath)
    $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)

$FoundAmount = 0
$log = @()
$T1 = "Processing "
$T2 = " ("
$T3 = " of "
$T4 = ")"
$counter = 0
$MailboxListCount = $MailboxList.count

$StartTime = Get-Date

Foreach ($MailboxName in $MailboxList)
{
$counter++

$Activity = $T1+$MailboxName+$T2+$counter+$T3+$MailboxListCount+$T4

$percent = (($counter/$MailboxListCount) * 100)

$percentstatus = [String]([System.Math]::Round($percent, 0)) + "`% complete"

Write-Progress -id 1 -PercentComplete $percent -Activity $activity -Status $percentstatus

$FoundFolder = $FALSE
$i = New-Object -TypeName PSObject
$i | Add-Member NoteProperty Email $MailboxName
if(Get-UMMailbox $MailboxName){$UMdisabled = "True"
    Disable-UMMailbox -Identity $MailboxName -KeepProperties:$True -Confirm:$false
$i | Add-Member NoteProperty UMdisabled "True"
}
else{
$i | Add-Member NoteProperty UMdisabled "NA"
}

#    $Service.AutodiscoverUrl($MailboxName,{$true})
    $service.Url= new-object Uri("https://outlook.uk2.practice.linklaters.net/EWS/Exchange.asmx")
    $RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,$MailboxName)
    $RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)
    $FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100,0)
    $FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow
    $Response = $RootFolder.FindFolders($FolderView)
    

    ForEach ($Folder in $Response.Folders){
            if($folder.DisplayName -eq "Skype for Business contacts"){
        ++$FoundAmount
$FoundFolder = $True
#$folder.delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
     #$folder.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete, $true)
$i | Add-Member NoteProperty Folder $folder.DisplayName
$i | Add-Member NoteProperty Action "Deleted"
}
    }
    if($FoundFolder -eq $false){
$i | Add-Member NoteProperty Folder "NotFound"
$i | Add-Member NoteProperty Action "None"
        }
$log += $i
}

$log | export-csv $logfilepath -notypeinformation -append

$StopTime = Get-Date
$TimeDiff = New-TimeSpan -Start $StartTime -End $StopTime
Write-Host "Deleted"$FoundAmount "folders in"$TimeDiff " and saved log to: "$logfilepath
}

Exchange Database statistics

DB sizes with whitespace:

Get-MailboxDatabase -Status | sort name | select name,@{Name='DB Size (Gb)';Expression={$_.DatabaseSize.ToGb()}},@{Name='Available New Mbx Space Gb)';Expression={$_.AvailableNewMailboxSpace.ToGb()}} | ft -auto


Database usage stats:


$dbs = Get-mailboxdatabase | select Name,Server | sort Name
$collcount = $dbs.count

$T1 = "Processing "
$T2 = " ("
$T3 = " of "
$T4 = ")"

$counter = 0

$results=@()
foreach($db in $databases){
$counter++

$Activity = $T1+$T2+$counter+$T3+$collcount+$T4

$percent = (($counter/$userscount) * 100)

$percentstatus = [String]([System.Math]::Round($percent, 0)) + "`% complete"

Write-Progress -PercentComplete $percent -Activity $activity -Status $percentstatus

$SUS = Get-StoreUsageStatistics -Database $db.name

$i = New-Object -TypeName PSObject
$i | Add-Member NoteProperty Database $db.name
$i | Add-Member NoteProperty Server $db.server
$i | Add-Member NoteProperty DisplayName $SUS.DisplayName
$i | Add-Member NoteProperty DigestCategory $SUS.DigestCategory
$i | Add-Member NoteProperty TimeInServer $SUS.TimeInServer
$i | Add-Member NoteProperty TimeInServer $SUS.TimeInCPU
$i | Add-Member NoteProperty SampleId $SUS.SampleId
$results += $i
}
$results | sort Server, TimeInServer -descending, Database | export-csv database-statistics.csv -notypeinformation

Functions 1

############## function to add append to export-csv #########################

function Export-CSV {
[CmdletBinding(DefaultParameterSetName='Delimiter',
  SupportsShouldProcess=$true, ConfirmImpact='Medium')]
param(
 [Parameter(Mandatory=$true, ValueFromPipeline=$true,
           ValueFromPipelineByPropertyName=$true)]
 [System.Management.Automation.PSObject]
 ${InputObject},

 [Parameter(Mandatory=$true, Position=0)]

 [Alias('PSPath')]
 [System.String]
 ${Path},

 [Switch]

 ${Append},

 [Switch]

 ${Force},

 [Switch]

 ${NoClobber},

 [ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32',

                  'BigEndianUnicode','Default','OEM')]
 [System.String]
 ${Encoding},

 [Parameter(ParameterSetName='Delimiter', Position=1)]

 [ValidateNotNull()]
 [System.Char]
 ${Delimiter},

 [Parameter(ParameterSetName='UseCulture')]

 [Switch]
 ${UseCulture},

 [Alias('NTI')]

 [Switch]
 ${NoTypeInformation})

begin

{
 $AppendMode = $false

 try {

  $outBuffer = $null
  if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
  {
      $PSBoundParameters['OutBuffer'] = 1
  }
  $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Csv',
    [System.Management.Automation.CommandTypes]::Cmdlet)
        
 $scriptCmdPipeline = ''

if ($Append) {

  
  $PSBoundParameters.Remove('Append') | Out-Null
    
  if ($Path) {
   if (Test-Path $Path) {        
    # Need to construct new command line
    $AppendMode = $true
    
    if ($Encoding.Length -eq 0) {
     $Encoding = 'ASCII'
    }
    
    $scriptCmdPipeline += 'ConvertTo-Csv -NoTypeInformation '

    if ( $UseCulture ) {

     $scriptCmdPipeline += ' -UseCulture '
    }
    if ( $Delimiter ) {
     $scriptCmdPipeline += " -Delimiter '$Delimiter' "
    } 
    
    $scriptCmdPipeline += ' | Foreach-Object {$start=$true}'
    $scriptCmdPipeline += '{if ($start) {$start=$false} else {$_}} '
    
    $scriptCmdPipeline += " | Out-File -FilePath '$Path'"
    $scriptCmdPipeline += " -Encoding '$Encoding' -Append "
    
    if ($Force) {
     $scriptCmdPipeline += ' -Force'
    }

    if ($NoClobber) {

     $scriptCmdPipeline += ' -NoClobber'
    }   
   }
  }
 } 
  
$scriptCmd = {& $wrappedCmd @PSBoundParameters }

 if ( $AppendMode ) {

  $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
      $scriptCmdPipeline
    )
 } else {
  $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
      [string]$scriptCmd
    )
 }

$steppablePipeline = $scriptCmd.GetSteppablePipeline(

        $myInvocation.CommandOrigin)
 $steppablePipeline.Begin($PSCmdlet)

 } catch {

   throw
 }
    
}

process

{
  try {
      $steppablePipeline.Process($_)
  } catch {
      throw
  }
}

end

{
  try {
      $steppablePipeline.End()
  } catch {
      throw
  }
}
}

######################################################################


function folder-statistics ($mailbox){
if(!($mailbox)){write-host -backgroundcolor yellow -foregroundcolor red "You must specify mailbox"}
else{
$INC = read-host "Enter INC reference"
$CurrentDate = (Get-Date).ToString('_MMM-dd-yyyy_HH-mm-ss_')
$outfile = "c:\users\me\documents\Reports\folderstats_" + $mailbox + $CurrentDate + $INC + ".csv"
[INT]$reportvalue = Read-host "Specify folder size value to report above"
$newhash = @()

$mbsize = Get-MailboxStatistics $mailbox | select TotalItemSize
[String]$mbsizestring = $mbsize.TotalItemSize
$mbSizeMB = [math]::Round(((((($mbsizestring.split("(")[1])).replace(" bytes)","")).replace(",","")))/1048576)
$mbSizeGB = [math]::Round(($mbSizeMB/1024),2)

$folderstats = Get-MailboxFolderStatistics $mailbox | select identity,name,FolderPath,FolderType,ItemsInFolder,DeletedItemsInFolder,FolderSize,ItemsInFolderAndSubfolders,DeletedItemsInFolderAndSubfolders,FolderAndSubfolderSize

foreach($fs in $folderstats){
[string]$foldersize = $fs.foldersize
$FolderSizeMB = [math]::Round(((((($foldersize.split("(")[1])).replace(" bytes)","")).replace(",","")))/1048576)
$FolderSizeGB = [String][System.math]::Round(($FolderSizeMB/1024),2)

$percentofmailbox = (($FolderSizeMB/$mbSizeMB) * 100)
$percentrounded = [string]([System.Math]::Round($percentofmailbox,2))

[string]$identity=$fs.identity

$i = New-Object -TypeName PSObject
$i | Add-Member NoteProperty User $mailbox
$i | Add-Member NoteProperty TotalSize $mbSizeGB
$i | Add-Member NoteProperty Identity $identity.replace($mailbox,"")
$i | Add-Member NoteProperty Name $fs.name
$i | Add-Member NoteProperty GBFolderSize $FolderSizeGB
$i | Add-Member NoteProperty MBFolderSize $FolderSizeMB
$i | Add-Member NoteProperty PerCent $percentrounded
$i | Add-Member NoteProperty ItemsInFolder $fs.ItemsInFolder
$i | Add-Member NoteProperty DeletedItemsInFolder $fs.DeletedItemsInFolder
$i | Add-Member NoteProperty FolderPath $fs.FolderPath
if($FolderSizeMB -gt $reportvalue){
$newhash += $i
}
}
$newhash = $newhash | sort MBFolderSize -descending | export-csv $outfile -NoTypeInformation
start-process excel.exe $outfile
}
}

######################################################################

function enumerate-dl ($dl){
$users = Get-DistributionGroupMember $dl | ?{$_.RecipientType -like "Use*"} | select name | sort name
$groups = Get-DistributionGroupMember $dl | ?{$_.RecipientType -like "*Group"} | select name | sort name

if($groups){Write-Host -foregroundcolor yellow "Nested groups:"
$groups | ft -hidetableheaders}
else{Write-Host -foregroundcolor green "No nested groups found"}

if($users){Write-Host -foregroundcolor white "Users:"
$users | ft -hidetableheaders}
else{Write-Host -foregroundcolor yellow "No users found"}
}

######################################################################

function queues {
$Global:hubs = Get-TransportServer
foreach($hub in $hubs){get-queue -Server $hub | ?{$_.MessageCount -gt 1 -and $_.DeliveryType -notlike "shadow*"}}
}

######################################################################

PS profile variables & transcript

$Global:scripts = "C:\Users\me\Documents\scripts"
$Global:reports = "C:\Users\me\Documents\Reports"

[string]$date = get-date -format "_dd-MMM-yy_HH-mm-ss"


$basepath = $env:userprofile + "\documents\pstranscripts\"


if((test-path $basepath) -eq $false){New-item –ItemType directory –force $basepath}


$Global:filepath = $basepath + "pstranscript" + $date + ".txt"


start-transcript -Path $filepath

Snippets for PsObject

This one pulls PrimarySMTP from ProxyAddresses:

ipmo ActiveDirectory

$PAS = Get-ADUser -Filter * -properties ProxyAddresses | select -ExpandProperty ProxyAddresses | ?{$_ -clike "SMTP:*"}


# (can use -SearchBase with DN of OU or foreach through a list of users)


foreach($PA in $PAS){


if($PA){$smtp = $PA.split(":")[1]}


# (get just the e-mail address)


if($PA){

[string]$cn = "CN=" + $PA.samaccountname + ","
[string]$DN = $PA.DistinguishedName
$oudn = $DN.replace($cn,"")
$truncoudn = $oudn.replace(",DC=domain,DC=com","")
if($truncoudn -notlike "*Mail Enabled*"){

$i = New-Object -TypeName PSObject

$i | Add-Member NoteProperty SamAccountName $PA.samaccountname
$i | Add-Member NoteProperty TruncOU $truncoudn

$results += $i


}}}