diff --git a/Databases/VSSTester/VSSTester.ps1 b/Databases/VSSTester/VSSTester.ps1 index c14041a59c..7f87e3de70 100644 --- a/Databases/VSSTester/VSSTester.ps1 +++ b/Databases/VSSTester/VSSTester.ps1 @@ -21,8 +21,6 @@ param( ) . $PSScriptRoot\..\..\Shared\Confirm-ExchangeShell.ps1 -. $PSScriptRoot\..\..\Shared\Write-HostWriter.ps1 -. $PSScriptRoot\..\..\Shared\Write-VerboseWriter.ps1 . .\DiskShadow\Invoke-CreateDiskShadowFile.ps1 . .\DiskShadow\Invoke-DiskShadow.ps1 . .\DiskShadow\Invoke-RemoveExposedDrives.ps1 diff --git a/Diagnostics/ExchangeLogCollector/ExchangeLogCollector.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeLogCollector.ps1 index 200250b3d1..fa6d532386 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeLogCollector.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeLogCollector.ps1 @@ -76,104 +76,52 @@ Param ( $BuildVersion = "" -$Script:VerboseEnabled = $false - -if ($PSBoundParameters["Verbose"]) { $Script:VerboseEnabled = $true } +if ($PSBoundParameters["Verbose"]) { $Script:ScriptDebug = $true } if ($PSCmdlet.ParameterSetName -eq "Worth") { $Script:LogAge = New-TimeSpan -Days $DaysWorth -Hours $HoursWorth } -. $PSScriptRoot\..\..\Shared\Confirm-Administrator.ps1 -. $PSScriptRoot\..\..\Shared\Confirm-ExchangeShell.ps1 -. .\extern\Enter-YesNoLoopAction.ps1 -. .\extern\Import-ScriptConfigFile.ps1 -. .\extern\Start-JobManager.ps1 -. .\ExchangeServerInfo\Get-DAGInformation.ps1 -. .\ExchangeServerInfo\Get-ExchangeBasicServerObject.ps1 -. .\ExchangeServerInfo\Get-ServerObjects.ps1 -. .\ExchangeServerInfo\Get-TransportLoggingInformationPerServer.ps1 -. .\ExchangeServerInfo\Get-VirtualDirectoriesLdap.ps1 -. .\Write\Get-WritersToAddToScriptBlock.ps1 -. .\Write\Write-DataOnlyOnceOnMasterServer.ps1 -. .\Write\Write-LargeDataObjectsOnMachine.ps1 -. .\Helpers\Get-ArgumentList.ps1 -. .\Helpers\Invoke-ServerRootZipAndCopy.ps1 -. .\Helpers\Test-DiskSpace.ps1 -. .\Helpers\Test-NoSwitchesProvided.ps1 -. .\Helpers\Test-PossibleCommonScenarios.ps1 -. .\Helpers\Test-RemoteExecutionOfServers.ps1 - Function Invoke-RemoteFunctions { param( [Parameter(Mandatory = $true)][object]$PassedInfo ) - . .\RemoteScriptBlock\extern\Compress-Folder.ps1 - . .\RemoteScriptBlock\extern\Get-ClusterNodeFileVersions.ps1 - . .\RemoteScriptBlock\extern\Get-ExchangeInstallDirectory.ps1 - . .\RemoteScriptBlock\extern\Get-FreeSpace.ps1 - . .\RemoteScriptBlock\extern\New-Folder.ps1 - . $PSScriptRoot\..\..\Shared\New-LoggerObject.ps1 - . .\RemoteScriptBlock\extern\Save-DataToFile.ps1 - . $PSScriptRoot\..\..\Shared\Write-HostWriter.ps1 - . .\RemoteScriptBlock\extern\Write-InvokeCommandReturnHostWriter.ps1 - . .\RemoteScriptBlock\extern\Write-InvokeCommandReturnVerboseWriter.ps1 - . .\RemoteScriptBlock\extern\Write-ScriptMethodHostWriter.ps1 - . $PSScriptRoot\..\..\Shared\Write-ScriptMethodVerboseWriter.ps1 - . $PSScriptRoot\..\..\Shared\Write-VerboseWriter.ps1 - . .\RemoteScriptBlock\Add-ServerNameToFileName.ps1 - . .\RemoteScriptBlock\Get-ItemsSize.ps1 - . .\RemoteScriptBlock\Get-StringDataForNotEnoughFreeSpace.ps1 - . .\RemoteScriptBlock\Get-IISLogDirectory.ps1 - . .\RemoteScriptBlock\Test-CommandExists.ps1 - . .\RemoteScriptBlock\Test-FreeSpace.ps1 - . .\RemoteScriptBlock\Invoke-ZipFolder.ps1 - . .\RemoteScriptBlock\IO\Copy-BulkItems.ps1 - . .\RemoteScriptBlock\IO\Copy-FullLogFullPathRecurse.ps1 - . .\RemoteScriptBlock\IO\Copy-LogmanData.ps1 - . .\RemoteScriptBlock\IO\Copy-LogsBasedOnTime.ps1 - . .\RemoteScriptBlock\IO\Invoke-CatchBlockActions.ps1 - . .\RemoteScriptBlock\IO\Save-DataInfoToFile.ps1 - . .\RemoteScriptBlock\IO\Save-FailoverClusterInformation.ps1 - . .\RemoteScriptBlock\IO\Save-LogmanExmonData.ps1 - . .\RemoteScriptBlock\IO\Save-LogmanExperfwizData.ps1 - . .\RemoteScriptBlock\IO\Save-ServerInfoData.ps1 - . .\RemoteScriptBlock\IO\Save-WindowsEventLogs.ps1 - . .\RemoteScriptBlock\IO\Write-DebugLog.ps1 - . .\RemoteScriptBlock\IO\Write-ScriptDebug.ps1 - . .\RemoteScriptBlock\IO\Write-ScriptHost.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanData.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanExt.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanObject.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanRootPath.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanStartDate.ps1 - . .\RemoteScriptBlock\Logman\Get-LogmanStatus.ps1 - . .\RemoteScriptBlock\Logman\Start-Logman.ps1 - . .\RemoteScriptBlock\Logman\Stop-Logman.ps1 - . .\RemoteScriptBlock\Invoke-RemoteMain.ps1 + . $PSScriptRoot\..\..\Shared\LoggerFunctions.ps1 + . $PSScriptRoot\..\..\Shared\Write-Host.ps1 + . $PSScriptRoot\RemoteScriptBlock\Get-ExchangeInstallDirectory.ps1 + . $PSScriptRoot\RemoteScriptBlock\Invoke-ZipFolder.ps1 + . $PSScriptRoot\RemoteScriptBlock\IO\Invoke-CatchBlockActions.ps1 + . $PSScriptRoot\RemoteScriptBlock\IO\Write-Verbose.ps1 + . $PSScriptRoot\RemoteScriptBlock\IO\WriteFunctions.ps1 + . $PSScriptRoot\RemoteScriptBlock\Invoke-RemoteMain.ps1 try { - $Script:VerboseFunctionCaller = ${Function:Write-ScriptDebug} - $Script:HostFunctionCaller = ${Function:Write-ScriptHost} if ($PassedInfo.ByPass -ne $true) { $Script:RootCopyToDirectory = "{0}{1}" -f $PassedInfo.RootFilePath, $env:COMPUTERNAME - $Script:Logger = New-LoggerObject -LogDirectory $Script:RootCopyToDirectory -LogName ("ExchangeLogCollector-Instance-Debug") ` - -HostFunctionCaller $Script:HostFunctionCaller ` - -VerboseFunctionCaller $Script:VerboseFunctionCaller - Write-ScriptDebug("Root Copy To Directory: $Script:RootCopyToDirectory") + $Script:Logger = Get-NewLoggerInstance -LogName "ExchangeLogCollector-Instance-Debug" -LogDirectory $Script:RootCopyToDirectory + SetWriteHostManipulateObjectAction ${Function:Get-ManipulateWriteHostValue} + SetWriteVerboseManipulateMessageAction ${Function:Get-ManipulateWriteVerboseValue} + SetWriteHostAction ${Function:Write-DebugLog} + SetWriteVerboseAction ${Function:Write-DebugLog} + + if ($PassedInfo.ScriptDebug) { + $Script:VerbosePreference = "Continue" + } + + Write-Verbose("Root Copy To Directory: $Script:RootCopyToDirectory") Invoke-RemoteMain } else { - Write-ScriptDebug("Loading common functions") + Write-Verbose("Loading common functions") } } catch { - Write-ScriptHost -WriteString ("An error occurred in Invoke-RemoteFunctions") -ForegroundColor "Red" + Write-Host "An error occurred in Invoke-RemoteFunctions" -ForegroundColor "Red" Invoke-CatchBlockActions #This is a bad place to catch the error that just occurred #Being that there is a try catch block around each command that we run now, we should never hit an issue here unless it is is prior to that. - Write-ScriptDebug "Critical Failure occurred." + Write-Verbose "Critical Failure occurred." } finally { - Write-ScriptDebug("Exiting: Invoke-RemoteFunctions") - Write-ScriptDebug("[double]TotalBytesSizeCopied: {0} | [double]TotalBytesSizeCompressed: {1} | [double]AdditionalFreeSpaceCushionGB: {2} | [double]CurrentFreeSpaceGB: {3} | [double]FreeSpaceMinusCopiedAndCompressedGB: {4}" -f $Script:TotalBytesSizeCopied, + Write-Verbose("Exiting: Invoke-RemoteFunctions") + Write-Verbose("[double]TotalBytesSizeCopied: {0} | [double]TotalBytesSizeCompressed: {1} | [double]AdditionalFreeSpaceCushionGB: {2} | [double]CurrentFreeSpaceGB: {3} | [double]FreeSpaceMinusCopiedAndCompressedGB: {4}" -f $Script:TotalBytesSizeCopied, $Script:TotalBytesSizeCompressed, $Script:AdditionalFreeSpaceCushionGB, $Script:CurrentFreeSpaceGB, @@ -181,6 +129,20 @@ Function Invoke-RemoteFunctions { } } +# Need to dot load the files outside of the remote functions after them to avoid issues with encapsulation +. $PSScriptRoot\..\..\Shared\Confirm-Administrator.ps1 +. $PSScriptRoot\..\..\Shared\Confirm-ExchangeShell.ps1 +. $PSScriptRoot\Write\Write-DataOnlyOnceOnMasterServer.ps1 +. $PSScriptRoot\Write\Write-LargeDataObjectsOnMachine.ps1 +. $PSScriptRoot\Helpers\Enter-YesNoLoopAction.ps1 +. $PSScriptRoot\Helpers\Get-ArgumentList.ps1 +. $PSScriptRoot\Helpers\Import-ScriptConfigFile.ps1 +. $PSScriptRoot\Helpers\Invoke-ServerRootZipAndCopy.ps1 +. $PSScriptRoot\Helpers\Test-DiskSpace.ps1 +. $PSScriptRoot\Helpers\Test-NoSwitchesProvided.ps1 +. $PSScriptRoot\Helpers\Test-PossibleCommonScenarios.ps1 +. $PSScriptRoot\Helpers\Test-RemoteExecutionOfServers.ps1 + Function Main { Start-Sleep 1 @@ -209,21 +171,21 @@ Function Main { "@ -f $BuildVersion, ($Script:StandardFreeSpaceInGBCheckSize = 10), $Script:StandardFreeSpaceInGBCheckSize Clear-Host - Write-ScriptHost -WriteString $display -ShowServer $false + Write-Host $display if (-not($AcceptEULA)) { Enter-YesNoLoopAction -Question "Do you wish to continue? " -YesAction {} -NoAction { exit } } if (-not (Confirm-Administrator)) { - Write-ScriptHost -WriteString ("Hey! The script needs to be executed in elevated mode. Start the Exchange Management Shell as an Administrator.") -ForegroundColor "Yellow" + Write-Host "Hey! The script needs to be executed in elevated mode. Start the Exchange Management Shell as an Administrator." -ForegroundColor "Yellow" exit } $Script:LocalExchangeShell = Confirm-ExchangeShell -Identity $env:COMPUTERNAME if (!($Script:LocalExchangeShell.ShellLoaded)) { - Write-ScriptHost -WriteString ("It appears that you are not on an Exchange 2010 or newer server. Sorry I am going to quit.") -ShowServer $false + Write-Host "It appears that you are not on an Exchange 2010 or newer server. Sorry I am going to quit." exit } @@ -234,7 +196,7 @@ Function Main { if ($Script:LocalExchangeShell.EdgeServer) { #If we are on an Exchange Edge Server, we are going to treat it like a single server on purpose as we recommend that the Edge Server is a non domain joined computer. #Because it isn't a domain joined computer, we can't use remote execution - Write-ScriptHost -WriteString ("Determined that we are on an Edge Server, we can only use locally collection for this role.") -ForegroundColor "Yellow" + Write-Host "Determined that we are on an Edge Server, we can only use locally collection for this role." -ForegroundColor "Yellow" $Script:EdgeRoleDetected = $true $Servers = @($env:COMPUTERNAME) } @@ -268,21 +230,24 @@ Function Main { } else { if ($null -eq (Test-DiskSpace -Servers $env:COMPUTERNAME -Path $FilePath -CheckSize $Script:StandardFreeSpaceInGBCheckSize)) { - Write-ScriptHost -ShowServer $false -WriteString ("Failed to have enough space available locally. We can't continue with the data collection") -ForegroundColor "Yellow" + Write-Host "Failed to have enough space available locally. We can't continue with the data collection" -ForegroundColor "Yellow" exit } if (-not($Script:EdgeRoleDetected)) { - Write-ScriptHost -ShowServer $false -WriteString ("Note: Remote Collection is now possible for Windows Server 2012 and greater on the remote machine. Just use the -Servers paramater with a list of Exchange Server names") -ForegroundColor "Yellow" - Write-ScriptHost -ShowServer $false -WriteString ("Going to collect the data locally") + Write-Host "Note: Remote Collection is now possible for Windows Server 2012 and greater on the remote machine. Just use the -Servers parameter with a list of Exchange Server names" -ForegroundColor "Yellow" + Write-Host "Going to collect the data locally" } $Script:ArgumentList = (Get-ArgumentList -Servers $env:COMPUTERNAME) Invoke-RemoteFunctions -PassedInfo $Script:ArgumentList + # Don't manipulate the host object when running locally after the Invoke-RemoteFunctions to + # make it the same as when having multiple servers executing the script against. + SetWriteHostManipulateObjectAction $null Write-DataOnlyOnceOnMasterServer Write-LargeDataObjectsOnMachine Invoke-ServerRootZipAndCopy -RemoteExecute $false } - Write-ScriptHost -WriteString "`r`n`r`n`r`nLooks like the script is done. If you ran into any issues or have additional feedback, please feel free to reach out ExToolsFeedback@microsoft.com." -ShowServer $false + Write-Host "`r`n`r`n`r`nLooks like the script is done. If you ran into any issues or have additional feedback, please feel free to reach out ExToolsFeedback@microsoft.com." } #Need to do this here otherwise can't find the script path $configPath = "{0}\{1}.json" -f (Split-Path -Parent $MyInvocation.MyCommand.Path), (Split-Path -Leaf $MyInvocation.MyCommand.Path) @@ -303,21 +268,21 @@ try { try { Import-ScriptConfigFile -ScriptConfigFileLocation $configPath } catch { - Write-ScriptHost "Failed to load the config file at $configPath. `r`nPlease update the config file to be able to run 'ConvertFrom-Json' against it" -ForegroundColor "Red" + Write-Host "Failed to load the config file at $configPath. `r`nPlease update the config file to be able to run 'ConvertFrom-Json' against it" -ForegroundColor "Red" Invoke-CatchBlockActions Enter-YesNoLoopAction -Question "Do you wish to continue?" -YesAction {} -NoAction { exit } } } $Script:RootFilePath = "{0}\{1}\" -f $FilePath, (Get-Date -Format yyyyMd) - $Script:Logger = New-LoggerObject -LogDirectory ("{0}{1}" -f $RootFilePath, $env:COMPUTERNAME) -LogName "ExchangeLogCollector-Main-Debug" ` - -HostFunctionCaller $Script:HostFunctionCaller ` - -VerboseFunctionCaller $Script:VerboseFunctionCaller + $Script:Logger = Get-NewLoggerInstance -LogName "ExchangeLogCollector-Main-Debug" -LogDirectory ("$RootFilePath$env:COMPUTERNAME") + SetWriteVerboseAction ${Function:Write-DebugLog} + SetWriteHostAction ${Function:Write-DebugLog} Main } finally { if ($Script:VerboseEnabled -or ($Error.Count -ne $Script:ErrorsFromStartOfCopy)) { - $Script:Logger.RemoveLatestLogFile() + #$Script:Logger.RemoveLatestLogFile() } } diff --git a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-DAGInformation.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-DAGInformation.ps1 index dc22c7f56c..3583a59943 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-DAGInformation.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-DAGInformation.ps1 @@ -9,14 +9,14 @@ Function Get-DAGInformation { try { $dag = Get-DatabaseAvailabilityGroup $DAGName -Status -ErrorAction Stop } catch { - Write-ScriptDebug("Failed to run Get-DatabaseAvailabilityGroup on $DAGName") + Write-Verbose("Failed to run Get-DatabaseAvailabilityGroup on $DAGName") Invoke-CatchBlockActions } try { $dagNetwork = Get-DatabaseAvailabilityGroupNetwork $DAGName -ErrorAction Stop } catch { - Write-ScriptDebug("Failed to run Get-DatabaseAvailabilityGroupNetwork on $DAGName") + Write-Verbose("Failed to run Get-DatabaseAvailabilityGroupNetwork on $DAGName") Invoke-CatchBlockActions } diff --git a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ExchangeBasicServerObject.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ExchangeBasicServerObject.ps1 index d5f2f3eb46..63058ec495 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ExchangeBasicServerObject.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ExchangeBasicServerObject.ps1 @@ -1,126 +1,70 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\..\..\Shared\Get-ExchangeBuildVersionInformation.ps1 +#TODO: Create Pester Testing on this +# Used to get the Exchange Version information and what roles are set on the server. Function Get-ExchangeBasicServerObject { param( [Parameter(Mandatory = $true)][string]$ServerName, [Parameter(Mandatory = $false)][bool]$AddGetServerProperty = $false ) - Write-ScriptDebug("Function Enter: Get-ExchangeBasicServerObject") - Write-ScriptDebug("Passed: [string]ServerName: {0}" -f $ServerName) + Write-Verbose("Function Enter: $($MyInvocation.MyCommand)") + Write-Verbose("Passed: [string]ServerName: {0}" -f $ServerName) try { $getExchangeServer = Get-ExchangeServer $ServerName -Status -ErrorAction Stop } catch { - Write-ScriptHost -WriteString ("Failed to detect server {0} as an Exchange Server" -f $ServerName) -ShowServer $false -ForegroundColor "Red" + Write-Host "Failed to detect server $ServerName as an Exchange Server" -ForegroundColor "Red" Invoke-CatchBlockActions return $null } $exchAdminDisplayVersion = $getExchangeServer.AdminDisplayVersion $exchServerRole = $getExchangeServer.ServerRole - Write-ScriptDebug("AdminDisplayVersion: {0} | ServerRole: {1}" -f $exchAdminDisplayVersion.ToString(), $exchServerRole.ToString()) - if ($exchAdminDisplayVersion.GetType().Name -eq "string") { - $start = $exchAdminDisplayVersion.IndexOf(" ") - $split = $exchAdminDisplayVersion.Substring( $start + 1, 4).split('.') - [int]$major = $split[0] - [int]$minor = $split[1] - } - if ($exchAdminDisplayVersion.Major -eq 14 -or $major -eq 14) { - $exchVersion = 14 - } elseif ($exchAdminDisplayVersion.Major -eq 15 -or $major -eq 15) { - #determine if 2013/2016/2019 - if ($exchAdminDisplayVersion.Minor -eq 0 -or $minor -eq 0) { + Write-Verbose("AdminDisplayVersion: {0} | ServerRole: {1}" -f $exchAdminDisplayVersion.ToString(), $exchServerRole.ToString()) + $buildVersionInformation = Get-ExchangeBuildVersionInformation $exchAdminDisplayVersion + + if ($buildVersionInformation.Major -eq 15) { + if ($buildVersionInformation.Minor -eq 0) { $exchVersion = 15 - } elseif ($exchAdminDisplayVersion.Minor -eq 1 -or $minor -eq 1) { + } elseif ($buildVersionInformation.Minor -eq 1) { $exchVersion = 16 } else { $exchVersion = 19 } - } else { - Write-ScriptHost -WriteString ("Failed to determine what version server {0} is. AdminDisplayVersion: {1}." -f $ServerName, $exchAdminDisplayVersion.ToString()) -ShowServer $false -ForegroundColor "Red" - return $true - } - - Function Confirm-MailboxServer { - param([string]$Value) - if ($value -like "*Mailbox*" -and (-not(Confirm-EdgeServer -Value $Value))) { - return $true - } else { - return $false - } - } - - Function Confirm-CASServer { - param([string]$Value, [int]$Version) - if ((-not(Confirm-EdgeServer -Value $Value)) -and (($Version -ge 16) -or ($Value -like "*ClientAccess*"))) { - return $true - } else { - return $false - } - } - - Function Confirm-CASOnlyServer { - param([string]$Value) - if ($Value -eq "ClientAccess") { - return $true - } else { - return $false - } } - Function Confirm-MailboxOnlyServer { - param([string]$Value) - if ($Value -eq "Mailbox") { - return $true - } else { - return $false - } - } - - Function Confirm-HubServer { - param([string]$Value, [int]$Version) - if ((($Version -ge 15) -and (-not (Confirm-CASOnlyServer -Value $Value))) -or ($Value -like "*HubTransport*")) { - return $true - } else { - return $false - } - } + $mailbox = $exchServerRole -like "*Mailbox*" + $dagName = [string]::Empty + $exchangeServer = $null - Function Confirm-EdgeServer { - param([string]$Value) - if ($Value -eq "Edge") { - return $true - } else { - return $false - } - } - - $exchServerObject = New-Object PSCustomObject - $exchServerObject | Add-Member -MemberType NoteProperty -Name ServerName -Value ($getExchangeServer.Name.ToUpper()) - $exchServerObject | Add-Member -MemberType NoteProperty -Name Mailbox -Value (Confirm-MailboxServer -Value $exchServerRole) - $exchServerObject | Add-Member -MemberType NoteProperty -Name CAS -Value (Confirm-CASServer -Value $exchServerRole -version $exchVersion) - $exchServerObject | Add-Member -MemberType NoteProperty -Name Hub -Value (Confirm-HubServer -Value $exchServerRole -version $exchVersion) - $exchServerObject | Add-Member -MemberType NoteProperty -Name CASOnly -Value (Confirm-CASOnlyServer -Value $exchServerRole) - $exchServerObject | Add-Member -MemberType NoteProperty -Name MailboxOnly -Value (Confirm-MailboxOnlyServer -Value $exchServerRole) - $exchServerObject | Add-Member -MemberType NoteProperty -Name Edge -Value (Confirm-EdgeServer -Value $exchServerRole) - $exchServerObject | Add-Member -MemberType NoteProperty -Name Version -Value $exchVersion - - if ($exchServerObject.Mailbox) { + if ($mailbox) { $getMailboxServer = Get-MailboxServer $ServerName - $exchServerObject | Add-Member -MemberType NoteProperty -Name DAGMember -Value (![string]::IsNullOrEmpty($getMailboxServer.DatabaseAvailabilityGroup)) - if ($exchServerObject.DAGMember) { - $exchServerObject | Add-Member -MemberType NoteProperty -Name DAGName -Value ($getMailboxServer.DatabaseAvailabilityGroup.ToString()) + if (-not([string]::IsNullOrEmpty($getMailboxServer.DatabaseAvailabilityGroup))) { + $dagName = $getMailboxServer.DatabaseAvailabilityGroup.ToString() } - } else { - $exchServerObject | Add-Member -MemberType NoteProperty -Name DAGMember -Value $false } if ($AddGetServerProperty) { - $exchServerObject | Add-Member -MemberType NoteProperty -Name ExchangeServer -Value $getExchangeServer + $exchangeServer = $getExchangeServer + } + + $exchServerObject = [PSCustomObject]@{ + ServerName = $getExchangeServer.Name.ToUpper() + Mailbox = $mailbox + MailboxOnly = $exchServerRole -eq "Mailbox" + Hub = $exchVersion -ge 15 -and (-not ($exchServerRole -eq "ClientAccess")) + CAS = $exchServerRole -like "*ClientAccess*" + CASOnly = $exchServerRole -eq "ClientAccess" + Edge = $exchServerRole -eq "Edge" + Version = $exchVersion + DAGMember = (-not ([string]::IsNullOrEmpty($dagName))) + DAGName = $dagName + ExchangeServer = $exchangeServer } - Write-ScriptDebug("Mailbox: {0} | CAS: {1} | Hub: {2} | CASOnly: {3} | MailboxOnly: {4} | Edge: {5} | DAGMember {6} | Version: {7} | AnyTransportSwitchesEnabled: {8} | DAGName: {9}" -f $exchServerObject.Mailbox, + Write-Verbose("Mailbox: {0} | CAS: {1} | Hub: {2} | CASOnly: {3} | MailboxOnly: {4} | Edge: {5} | DAGMember {6} | Version: {7} | AnyTransportSwitchesEnabled: {8} | DAGName: {9}" -f $exchServerObject.Mailbox, $exchServerObject.CAS, $exchServerObject.Hub, $exchServerObject.CASOnly, diff --git a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ServerObjects.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ServerObjects.ps1 index b4b1c5f435..d77072c593 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ServerObjects.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-ServerObjects.ps1 @@ -1,21 +1,23 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-ExchangeBasicServerObject.ps1 +. $PSScriptRoot\Get-TransportLoggingInformationPerServer.ps1 Function Get-ServerObjects { param( [Parameter(Mandatory = $true)][Array]$ValidServers ) - Write-ScriptDebug ("Function Enter: Get-ServerObjects") - Write-ScriptDebug ("Passed: {0} number of Servers" -f $ValidServers.Count) + Write-Verbose ("Function Enter: Get-ServerObjects") + Write-Verbose ("Passed: {0} number of Servers" -f $ValidServers.Count) $svrsObject = @() $validServersList = @() foreach ($svr in $ValidServers) { - Write-ScriptDebug ("Working on Server {0}" -f $svr) + Write-Verbose ("Working on Server {0}" -f $svr) $sobj = Get-ExchangeBasicServerObject -ServerName $svr if ($sobj -eq $true) { - Write-ScriptHost -WriteString ("Removing Server {0} from the list" -f $svr) -ForegroundColor "Red" -ShowServer $false + Write-Host "Removing Server $svr from the list" -ForegroundColor "Red" continue } else { $validServersList += $svr @@ -48,11 +50,11 @@ Function Get-ServerObjects { if (($null -eq $svrsObject) -or ($svrsObject.Count -eq 0)) { - Write-ScriptHost -WriteString ("Something wrong happened in Get-ServerObjects stopping script") -ShowServer $false -ForegroundColor "Red" + Write-Host "Something wrong happened in Get-ServerObjects stopping script" -ForegroundColor "Red" exit } #Set the valid servers $Script:ValidServers = $validServersList - Write-ScriptDebug("Function Exit: Get-ServerObjects") + Write-Verbose("Function Exit: Get-ServerObjects") Return $svrsObject } diff --git a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-TransportLoggingInformationPerServer.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-TransportLoggingInformationPerServer.ps1 index 96d64af1f6..806ef0b165 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-TransportLoggingInformationPerServer.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-TransportLoggingInformationPerServer.ps1 @@ -9,8 +9,8 @@ Function Get-TransportLoggingInformationPerServer { [bool]$CASOnly, [bool]$MailboxOnly ) - Write-ScriptDebug("Function Enter: Get-TransportLoggingInformationPerServer") - Write-ScriptDebug("Passed: [string]Server: {0} | [int]Version: {1} | [bool]EdgeServer: {2} | [bool]CASOnly: {3} | [bool]MailboxOnly: {4}" -f $Server, $Version, $EdgeServer, $CASOnly, $MailboxOnly) + Write-Verbose("Function Enter: Get-TransportLoggingInformationPerServer") + Write-Verbose("Passed: [string]Server: {0} | [int]Version: {1} | [bool]EdgeServer: {2} | [bool]CASOnly: {3} | [bool]MailboxOnly: {4}" -f $Server, $Version, $EdgeServer, $CASOnly, $MailboxOnly) $transportLoggingObject = New-Object PSCustomObject if ($Version -ge 15) { @@ -71,10 +71,10 @@ Function Get-TransportLoggingInformationPerServer { $hubObject | Add-Member -MemberType NoteProperty -Name SendProtocolLogPath -Value ($data.SendProtocolLogPath.PathName) $transportLoggingObject | Add-Member -MemberType NoteProperty -Name HubLoggingInfo -Value $hubObject } else { - Write-ScriptHost -WriteString ("trying to determine transport information for server {0} and wasn't able to determine the correct version type" -f $Server) -ShowServer $false + Write-Host "trying to determine transport information for server $Server and wasn't able to determine the correct version type" return } - Write-ScriptDebug("Function Exit: Get-TransportLoggingInformationPerServer") + Write-Verbose("Function Exit: Get-TransportLoggingInformationPerServer") return $transportLoggingObject } diff --git a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-VirtualDirectoriesLdap.ps1 b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-VirtualDirectoriesLdap.ps1 index 6973889860..50a0cbff51 100644 --- a/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-VirtualDirectoriesLdap.ps1 +++ b/Diagnostics/ExchangeLogCollector/ExchangeServerInfo/Get-VirtualDirectoriesLdap.ps1 @@ -31,7 +31,7 @@ Function Get-VirtualDirectoriesLdap { } "@ - Write-ScriptHost -WriteString "Collecting Virtual Directory Information..." -ShowServer $false + Write-Host "Collecting Virtual Directory Information..." Add-Type -TypeDefinition $authTypeEnum -Language CSharp $objRootDSE = [ADSI]"LDAP://rootDSE" diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Add-ScriptBlockInjection.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Add-ScriptBlockInjection.ps1 new file mode 100644 index 0000000000..56e010b729 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/Helpers/Add-ScriptBlockInjection.ps1 @@ -0,0 +1,145 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +. $PSScriptRoot\..\..\..\Shared\Invoke-CatchActionError.ps1 + +# Injects Verbose and Debug Preferences and other passed variables into the script block +# It will also inject any additional script blocks into the main script block. +# This allows for an Invoke-Command to work as intended if multiple functions/script blocks are required. +Function Add-ScriptBlockInjection { + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Mandatory = $true)] + [scriptblock]$PrimaryScriptBlock, + + [string[]]$IncludeUsingParameter, + + [scriptblock[]]$IncludeScriptBlock, + + [scriptblock] + $CatchActionFunction + ) + process { + try { + # In Remote Execution if you want Write-Verbose to work or add in additional + # Script Blocks to your code to be executed, like a custom Write-Verbose, you need to inject it into the script block + # that is passed to Invoke-Command. + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + $scriptBlockInjectLines = @() + $scriptBlockFinalized = [string]::Empty + $adjustedScriptBlock = $PrimaryScriptBlock + $injectedLinesHandledInBeginBlock = $false + $adjustInject = $false + + if ($null -ne $IncludeUsingParameter) { + $lines = @() + $lines += 'if ($PSSenderInfo) {' + $IncludeUsingParameter | ForEach-Object { + $lines += '$name=$Using:name'.Replace("name", "$_") + } + $lines += "}" + [System.Environment]::NewLine + $usingLines = $lines -join [System.Environment]::NewLine + } else { + $usingLines = [System.Environment]::NewLine + } + + if ($null -ne $IncludeScriptBlock) { + $lines = @() + $IncludeScriptBlock | ForEach-Object { + $lines += "Function $($_.Ast.Name) { $([System.Environment]::NewLine)" + $lines += "$($_.ToString().Trim()) $([System.Environment]::NewLine) } $([System.Environment]::NewLine)" + } + $scriptBlockIncludeLines = $lines -join [System.Environment]::NewLine + } else { + $scriptBlockIncludeLines = [System.Environment]::NewLine + } + + # There are a few different ways to create a script block + # [scriptblock]::Create(string) and ${Function:Write-Verbose} + # each one ends up adding in the ParamBlock at different locations + # You need to add in the injected code after the params, if that is the only thing that is passed + # If you provide a script block that contains a begin or a process section, + # you need to add the injected code into the begin block. + # Here you need to find the ParamBlock and add it to the inject lines to be at the top of the script block. + # Then you need to recreate the adjustedScriptBlock to be where the ParamBlock ended. + + if ($null -ne $PrimaryScriptBlock.Ast.ParamBlock) { + Write-Verbose "Ast ParamBlock detected" + $adjustLocation = $PrimaryScriptBlock.Ast + } elseif ($null -ne $PrimaryScriptBlock.Ast.Body.ParamBlock) { + Write-Verbose "Ast Body ParamBlock detected" + $adjustLocation = $PrimaryScriptBlock.Ast.Body + } + + $adjustInject = $null -ne $PrimaryScriptBlock.Ast.ParamBlock -or $null -ne $PrimaryScriptBlock.Ast.Body.ParamBlock + + if ($adjustInject) { + $scriptBlockInjectLines += $adjustLocation.ParamBlock.ToString() + $startIndex = $adjustLocation.ParamBlock.Extent.EndOffSet - $adjustLocation.Extent.StartOffset + $adjustedScriptBlock = [scriptblock]::Create($PrimaryScriptBlock.ToString().Substring($startIndex)) + } + + # Inject the script blocks and using parameters in the begin block when required. + if ($null -ne $adjustedScriptBlock.Ast.BeginBlock) { + Write-Verbose "Ast BeginBlock detected" + $replaceMatch = $adjustedScriptBlock.Ast.BeginBlock.Extent.ToString() + $addString = [string]::Empty + [System.Environment]::NewLine + $addString += { + if ($PSSenderInfo) { + $VerbosePreference = $Using:VerbosePreference + $DebugPreference = $Using:DebugPreference + } + } + $addString += [System.Environment]::NewLine + $usingLines + $scriptBlockIncludeLines + $startIndex = $replaceMatch.IndexOf("{") + #insert the adding context to one character after the begin curl bracket + $replaceWith = $replaceMatch.Insert($startIndex + 1, $addString) + $adjustedScriptBlock = [scriptblock]::Create($adjustedScriptBlock.ToString().Replace($replaceMatch, $replaceWith)) + $injectedLinesHandledInBeginBlock = $true + } elseif ($null -ne $adjustedScriptBlock.Ast.ProcessBlock) { + # Add in a begin block that contains all information that we are wanting. + Write-Verbose "Ast Process Block detected" + $addString = [string]::Empty + [System.Environment]::NewLine + $addString += { + begin { + if ($PSScriptRoot) { + $VerbosePreference = $Using:VerbosePreference + $DebugPreference = $Using:DebugPreference + } + } + } + $endIndex = $addString.LastIndexOf("}") - 1 + $addString = $addString.insert($endIndex, [System.Environment]::NewLine + $usingLines + $scriptBlockIncludeLines + [System.Environment]::NewLine ) + $startIndex = $adjustedScriptBlock.Ast.ProcessBlock.Extent.StartOffset - 1 + $adjustedScriptBlock = [scriptblock]::Create($adjustedScriptBlock.ToString().Insert($startIndex, $addString)) + $injectedLinesHandledInBeginBlock = $true + } else { + Write-Verbose "No Begin or Process Blocks detected, normal injection" + $scriptBlockInjectLines += { + if ($PSSenderInfo) { + $VerbosePreference = $Using:VerbosePreference + $DebugPreference = $Using:DebugPreference + } + } + } + + if (-not $injectedLinesHandledInBeginBlock) { + $scriptBlockInjectLines += $usingLines + $scriptBlockIncludeLines + [System.Environment]::NewLine + } + + # Combined the injected lines and the main script block together + # then create a new script block from finalized result + $scriptBlockInjectLines += $adjustedScriptBlock + $scriptBlockInjectLines | ForEach-Object { + $scriptBlockFinalized += $_.ToString() + [System.Environment]::NewLine + } + + #Need to return a string type otherwise run into issues. + return $scriptBlockFinalized + } catch { + Write-Verbose "Failed to add to the script block" + Invoke-CatchActionError $CatchActionFunction + } + } +} diff --git a/Diagnostics/ExchangeLogCollector/extern/Enter-YesNoLoopAction.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Enter-YesNoLoopAction.ps1 similarity index 59% rename from Diagnostics/ExchangeLogCollector/extern/Enter-YesNoLoopAction.ps1 rename to Diagnostics/ExchangeLogCollector/Helpers/Enter-YesNoLoopAction.ps1 index f68e7ee85c..0c033bfa1d 100644 --- a/Diagnostics/ExchangeLogCollector/extern/Enter-YesNoLoopAction.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Enter-YesNoLoopAction.ps1 @@ -1,8 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Enter-YesNoLoopAction/Enter-YesNoLoopAction.ps1 -#v21.01.22.2234 Function Enter-YesNoLoopAction { [CmdletBinding()] param( @@ -10,14 +8,13 @@ Function Enter-YesNoLoopAction { [Parameter(Mandatory = $true)][scriptblock]$YesAction, [Parameter(Mandatory = $true)][scriptblock]$NoAction ) - #Function Version #v21.01.22.2234 - Write-VerboseWriter("Calling: Enter-YesNoLoopAction") - Write-VerboseWriter("Passed: [string]Question: {0}" -f $Question) + Write-Verbose "Calling: Enter-YesNoLoopAction" + Write-Verbose "Passed: [string]Question: $Question" do { $answer = Read-Host ("{0} ('y' or 'n')" -f $Question) - Write-VerboseWriter("Read-Host answer: {0}" -f $answer) + Write-Verbose "Read-Host answer: $answer" }while ($answer -ne 'n' -and $answer -ne 'y') if ($answer -eq 'y') { diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Get-ArgumentList.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Get-ArgumentList.ps1 index 019179112f..e4f9ac43f9 100644 --- a/Diagnostics/ExchangeLogCollector/Helpers/Get-ArgumentList.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Get-ArgumentList.ps1 @@ -1,8 +1,8 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\ExchangeServerInfo\Get-ServerObjects.ps1 Function Get-ArgumentList { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = 'TODO: Change this')] param( [Parameter(Mandatory = $true)][array]$Servers ) @@ -23,58 +23,57 @@ Function Get-ArgumentList { $Script:MasterServer = $Servers[0] } - $obj = New-Object PSCustomObject - $obj | Add-Member -Name FilePath -MemberType NoteProperty -Value $FilePath - $obj | Add-Member -Name RootFilePath -MemberType NoteProperty -Value $Script:RootFilePath - $obj | Add-Member -Name ServerObjects -MemberType NoteProperty -Value (Get-ServerObjects -ValidServers $Servers) - $obj | Add-Member -Name ManagedAvailabilityLogs -MemberType NoteProperty -Value $ManagedAvailabilityLogs - $obj | Add-Member -Name AppSysLogs -MemberType NoteProperty -Value $AppSysLogs - $obj | Add-Member -Name AppSysLogsToXml -MemberType NoteProperty -Value $AppSysLogsToXml - $obj | Add-Member -Name EWSLogs -MemberType NoteProperty -Value $EWSLogs - $obj | Add-Member -Name DailyPerformanceLogs -MemberType NoteProperty -Value $DailyPerformanceLogs - $obj | Add-Member -Name RPCLogs -MemberType NoteProperty -Value $RPCLogs - $obj | Add-Member -Name EASLogs -MemberType NoteProperty -Value $EASLogs - $obj | Add-Member -Name ECPLogs -MemberType NoteProperty -Value $ECPLogs - $obj | Add-Member -Name AutoDLogs -MemberType NoteProperty -Value $AutoDLogs - $obj | Add-Member -Name OWALogs -MemberType NoteProperty -Value $OWALogs - $obj | Add-Member -Name ADDriverLogs -MemberType NoteProperty -Value $ADDriverLogs - $obj | Add-Member -Name SearchLogs -MemberType NoteProperty -Value $SearchLogs - $obj | Add-Member -Name HighAvailabilityLogs -MemberType NoteProperty -Value $HighAvailabilityLogs - $obj | Add-Member -Name MapiLogs -MemberType NoteProperty -Value $MapiLogs - $obj | Add-Member -Name MessageTrackingLogs -MemberType NoteProperty -Value $MessageTrackingLogs - $obj | Add-Member -Name HubProtocolLogs -MemberType NoteProperty -Value $HubProtocolLogs - $obj | Add-Member -Name HubConnectivityLogs -MemberType NoteProperty -Value $HubConnectivityLogs - $obj | Add-Member -Name FrontEndConnectivityLogs -MemberType NoteProperty -Value $FrontEndConnectivityLogs - $obj | Add-Member -Name FrontEndProtocolLogs -MemberType NoteProperty -Value $FrontEndProtocolLogs - $obj | Add-Member -Name MailboxConnectivityLogs -MemberType NoteProperty -Value $MailboxConnectivityLogs - $obj | Add-Member -Name MailboxProtocolLogs -MemberType NoteProperty -Value $MailboxProtocolLogs - $obj | Add-Member -Name MailboxDeliveryThrottlingLogs -MemberType NoteProperty -Value $MailboxDeliveryThrottlingLogs - $obj | Add-Member -Name QueueInformation -MemberType NoteProperty -Value $QueueInformation - $obj | Add-Member -Name SendConnectors -MemberType NoteProperty -Value $SendConnectors - $obj | Add-Member -Name DAGInformation -MemberType NoteProperty -Value $DAGInformation - $obj | Add-Member -Name GetVdirs -MemberType NoteProperty -Value $GetVdirs - $obj | Add-Member -Name TransportConfig -MemberType NoteProperty -Value $TransportConfig - $obj | Add-Member -Name DefaultTransportLogging -MemberType NoteProperty -Value $DefaultTransportLogging - $obj | Add-Member -Name ServerInformation -MemberType NoteProperty -Value $ServerInformation - $obj | Add-Member -Name CollectAllLogsBasedOnLogAge -MemberType NoteProperty -Value $CollectAllLogsBasedOnLogAge - $obj | Add-Member -Name TimeSpan -MemberType NoteProperty -Value $LogAge - $obj | Add-Member -Name IISLogs -MemberType NoteProperty -Value $IISLogs - $obj | Add-Member -Name AnyTransportSwitchesEnabled -MemberType NoteProperty -Value $script:AnyTransportSwitchesEnabled - $obj | Add-Member -Name HostExeServerName -MemberType NoteProperty -Value ($env:COMPUTERNAME) - $obj | Add-Member -Name Experfwiz -MemberType NoteProperty -Value $Experfwiz - $obj | Add-Member -Name ExperfwizLogmanName -MemberType NoteProperty -Value $ExperfwizLogmanName - $obj | Add-Member -Name Exmon -MemberType NoteProperty -Value $Exmon - $obj | Add-Member -Name ExmonLogmanName -MemberType NoteProperty -Value $ExmonLogmanName - $obj | Add-Member -Name ScriptDebug -MemberType NoteProperty -Value $ScriptDebug - $obj | Add-Member -Name ExchangeServerInformation -MemberType NoteProperty -Value $ExchangeServerInformation - $obj | Add-Member -Name StandardFreeSpaceInGBCheckSize -MemberType NoteProperty $Script:StandardFreeSpaceInGBCheckSize - $obj | Add-Member -Name PopLogs -MemberType NoteProperty -Value $PopLogs - $obj | Add-Member -Name ImapLogs -MemberType NoteProperty -Value $ImapLogs - $obj | Add-Member -Name OABLogs -MemberType NoteProperty -Value $OABLogs - $obj | Add-Member -Name PowerShellLogs -MemberType NoteProperty -Value $PowerShellLogs - $obj | Add-Member -Name WindowsSecurityLogs -MemberType NoteProperty $WindowsSecurityLogs - $obj | Add-Member -Name MasterServer -MemberType NoteProperty -Value $Script:MasterServer - $obj | Add-Member -Name MitigationService -MemberType NoteProperty -Value $MitigationService - - return $obj + return [PSCustomObject]@{ + ADDriverLogs = $ADDriverLogs + AnyTransportSwitchesEnabled = $Script:AnyTransportSwitchesEnabled + AppSysLogs = $AppSysLogs + AppSysLogsToXml = $AppSysLogsToXml + AutoDLogs = $AutoDLogs + CollectAllLogsBasedOnLogAge = $CollectAllLogsBasedOnLogAge + DAGInformation = $DAGInformation + DailyPerformanceLogs = $DailyPerformanceLogs + DefaultTransportLogging = $DefaultTransportLogging + EASLogs = $EASLogs + ECPLogs = $ECPLogs + EWSLogs = $EWSLogs + ExchangeServerInformation = $ExchangeServerInformation + Exmon = $Exmon + ExmonLogmanName = $ExmonLogmanName + Experfwiz = $Experfwiz + ExperfwizLogmanName = $ExperfwizLogmanName + FilePath = $FilePath + FrontEndConnectivityLogs = $FrontEndConnectivityLogs + FrontEndProtocolLogs = $FrontEndProtocolLogs + GetVdirs = $GetVdirs + HighAvailabilityLogs = $HighAvailabilityLogs + HostExeServerName = $env:COMPUTERNAME + HubConnectivityLogs = $HubConnectivityLogs + HubProtocolLogs = $HubProtocolLogs + IISLogs = $IISLogs + ImapLogs = $ImapLogs + TimeSpan = $LogAge + MailboxConnectivityLogs = $MailboxConnectivityLogs + MailboxDeliveryThrottlingLogs = $MailboxDeliveryThrottlingLogs + MailboxProtocolLogs = $MailboxProtocolLogs + ManagedAvailabilityLogs = $ManagedAvailabilityLogs + MapiLogs = $MapiLogs + MasterServer = $Script:MasterServer + MessageTrackingLogs = $MessageTrackingLogs + MitigationService = $MitigationService + OABLogs = $OABLogs + OWALogs = $OWALogs + PopLogs = $PopLogs + PowerShellLogs = $PowerShellLogs + QueueInformation = $QueueInformation + RootFilePath = $Script:RootFilePath + RPCLogs = $RPCLogs + SearchLogs = $SearchLogs + SendConnectors = $SendConnectors + ServerInformation = $ServerInformation + ServerObjects = (Get-ServerObjects -ValidServers $Servers) + ScriptDebug = $ScriptDebug + StandardFreeSpaceInGBCheckSize = $Script:StandardFreeSpaceInGBCheckSize + TransportConfig = $TransportConfig + WindowsSecurityLogs = $WindowsSecurityLogs + } } diff --git a/Diagnostics/ExchangeLogCollector/extern/Import-ScriptConfigFile.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Import-ScriptConfigFile.ps1 similarity index 50% rename from Diagnostics/ExchangeLogCollector/extern/Import-ScriptConfigFile.ps1 rename to Diagnostics/ExchangeLogCollector/Helpers/Import-ScriptConfigFile.ps1 index 292858d342..bf333c8789 100644 --- a/Diagnostics/ExchangeLogCollector/extern/Import-ScriptConfigFile.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Import-ScriptConfigFile.ps1 @@ -1,24 +1,16 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Import-ScriptConfigFile/Import-ScriptConfigFile.ps1 -#v21.02.07.1240 Function Import-ScriptConfigFile { [CmdletBinding()] param( - [Parameter( - Mandatory = $true - )] + [Parameter(Mandatory = $true)] + [ValidateScript({ Test-Path $_ })] [string]$ScriptConfigFileLocation ) - #Function Version #v21.02.07.1240 - Write-VerboseWriter("Calling: Import-ScriptConfigFile") - Write-VerboseWriter("Passed: [string]ScriptConfigFileLocation: '$ScriptConfigFileLocation'") - - if (!(Test-Path $ScriptConfigFileLocation)) { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid ScriptConfigFileLocation" - } + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + Write-Verbose "Passed: [string]ScriptConfigFileLocation: '$ScriptConfigFileLocation'" try { $content = Get-Content $ScriptConfigFileLocation -ErrorAction Stop @@ -31,7 +23,7 @@ Function Import-ScriptConfigFile { Get-Member | Where-Object { $_.Name -ne "Method" } | ForEach-Object { - Write-VerboseWriter("Adding variable $($_.Name)") + Write-Verbose "Adding variable $($_.Name)" Set-Variable -Name $_.Name -Value ($jsonContent.$($_.Name)) -Scope Script } } diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Invoke-ServerRootZipAndCopy.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Invoke-ServerRootZipAndCopy.ps1 index 7d18919643..ad14423ebd 100644 --- a/Diagnostics/ExchangeLogCollector/Helpers/Invoke-ServerRootZipAndCopy.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Invoke-ServerRootZipAndCopy.ps1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Start-JobManager.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\Get-FreeSpace.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Compress-Folder.ps1 #This function is to handle all root zipping capabilities and copying of the data over. Function Invoke-ServerRootZipAndCopy { param( @@ -13,23 +16,21 @@ Function Invoke-ServerRootZipAndCopy { } Function Write-CollectFilesFromLocation { - Write-ScriptHost -ShowServer $false -WriteString (" ") - Write-ScriptHost -ShowServer $false -WriteString ("Please collect the following files from these servers and upload them: ") + Write-Host "" + Write-Host "Please collect the following files from these servers and upload them: " $LogPaths | ForEach-Object { - Write-ScriptHost -ShowServer $false -WriteString ("Server: {0} Path: {1}" -f $_.ServerName, $_.ZipFolder) + Write-Host "Server: $($_.ServerName) Path: $($_.ZipFolder)" } } if ($RemoteExecute) { $Script:ErrorsFromStartOfCopy = $Error.Count - $Script:Logger = New-LoggerObject -LogDirectory $Script:RootFilePath -LogName "ExchangeLogCollector-ZipAndCopy-Debug" ` - -HostFunctionCaller $Script:HostFunctionCaller ` - -VerboseFunctionCaller $Script:VerboseFunctionCaller + $Script:Logger = Get-NewLoggerInstance -LogName "ExchangeLogCollector-ZipAndCopy-Debug" -LogDirectory $Script:RootFilePath - Write-ScriptDebug("Getting Compress-Folder string to create Script Block") - $compressFolderString = (${Function:Compress-Folder}).ToString().Replace("#Function Version", (Get-WritersToAddToScriptBlock)) - Write-ScriptDebug("Creating script block") + Write-Verbose("Getting Compress-Folder string to create Script Block") + $compressFolderString = (${Function:Compress-Folder}).ToString() + Write-Verbose("Creating script block") $compressFolderScriptBlock = [scriptblock]::Create($compressFolderString) $serverArgListZipFolder = @() @@ -39,17 +40,12 @@ Function Invoke-ServerRootZipAndCopy { $folder = "{0}{1}" -f $Script:RootFilePath, $serverName $serverArgListZipFolder += [PSCustomObject]@{ ServerName = $serverName - ArgumentList = [PSCustomObject]@{ - Folder = $folder - IncludeMonthDay = $true - IncludeDisplayZipping = $true - } + ArgumentList = @($folder, $true, $true) } } - Write-ScriptDebug("Calling Compress-Folder") + Write-Verbose("Calling Compress-Folder") Start-JobManager -ServersWithArguments $serverArgListZipFolder -ScriptBlock $compressFolderScriptBlock ` - -DisplayReceiveJobInCorrectFunction $true ` -JobBatchName "Zipping up the data for Invoke-ServerRootZipAndCopy" $LogPaths = Invoke-Command -ComputerName $serverNames -ScriptBlock { @@ -77,23 +73,23 @@ Function Invoke-ServerRootZipAndCopy { $totalSizeGB = $totalSizeToCopyOver / 1GB if ($freeSpace -gt ($totalSizeGB + $Script:StandardFreeSpaceInGBCheckSize)) { - Write-ScriptHost -ShowServer $true -WriteString ("Looks like we have enough free space at the path to copy over the data") - Write-ScriptHost -ShowServer $true -WriteString ("FreeSpace: {0} TestSize: {1} Path: {2}" -f $freeSpace, ($totalSizeGB + $Script:StandardFreeSpaceInGBCheckSize), $RootPath) - Write-ScriptHost -ShowServer $false -WriteString (" ") - Write-ScriptHost -ShowServer $false -WriteString ("Copying over the data may take some time depending on the network") + Write-Host "Looks like we have enough free space at the path to copy over the data" + Write-Host "FreeSpace: $freeSpace TestSize: $(($totalSizeGB + $Script:StandardFreeSpaceInGBCheckSize)) Path: $RootPath" + Write-Host "" + Write-Host "Copying over the data may take some time depending on the network" $LogPaths | ForEach-Object { if ($_.ServerName -ne $env:COMPUTERNAME) { $remoteCopyLocation = "\\{0}\{1}" -f $_.ServerName, ($_.ZipFolder.Replace(":", "$")) - Write-ScriptHost -ShowServer $false -WriteString ("[{0}] : Copying File {1}...." -f $_.ServerName, $remoteCopyLocation) + Write-Host "[$($_.ServerName)] : Copying File $remoteCopyLocation...." Copy-Item -Path $remoteCopyLocation -Destination $Script:RootFilePath - Write-ScriptHost -ShowServer $false -WriteString ("[{0}] : Done copying file" -f $_.ServerName) + Write-Host "[$($_.ServerName)] : Done copying file" } } } else { - Write-ScriptHost -ShowServer $true -WriteString("Looks like we don't have enough free space to copy over the data") -ForegroundColor "Yellow" - Write-ScriptHost -ShowServer $true -WriteString("FreeSpace: {0} TestSize: {1} Path: {2}" -f $FreeSpace, ($totalSizeGB + $Script:StandardFreeSpaceInGBCheckSize), $RootPath) + Write-Host "Looks like we don't have enough free space to copy over the data" -ForegroundColor "Yellow" + Write-Host "FreeSpace: $FreeSpace TestSize: $(($totalSizeGB + $Script:StandardFreeSpaceInGBCheckSize)) Path: $RootPath" Write-CollectFilesFromLocation } } else { diff --git a/Diagnostics/ExchangeLogCollector/Helpers/PipelineFunctions.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/PipelineFunctions.ps1 new file mode 100644 index 0000000000..21d3e411a1 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/Helpers/PipelineFunctions.ps1 @@ -0,0 +1,47 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function New-PipelineObject { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Caller knows that this is an action')] + [CmdletBinding()] + param( + [object]$Object, + [string]$Type + ) + process { + return [PSCustomObject]@{ + Object = $Object + Type = $Type + } + } +} + +Function Invoke-PipelineHandler { + [CmdletBinding()] + param( + [object[]]$Object + ) + process { + foreach ($instance in $Object) { + if ($instance.Type -eq "Verbose") { + Write-Verbose "$($instance.PSComputerName) - $($instance.Object)" + } elseif ($instance.Type -eq "Host") { + Write-Host $instance.Object + } else { + return $instance + } + } + } +} + +Function New-VerbosePipelineObject { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Caller knows that this is an action')] + [CmdletBinding()] + param( + [Parameter(Position = 1)] + [string]$Message + ) + process { + New-PipelineObject $Message "Verbose" + } +} diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Start-JobManager.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Start-JobManager.ps1 new file mode 100644 index 0000000000..361b6f9872 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/Helpers/Start-JobManager.ps1 @@ -0,0 +1,95 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function Start-JobManager { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'I prefer Start here')] + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [object[]]$ServersWithArguments, + + [Parameter(Mandatory = $true)] + [scriptblock]$ScriptBlock, + + [string]$JobBatchName, + + [bool]$DisplayReceiveJob = $true, + + [bool]$NeedReturnData = $false, + + [scriptblock]$RemotePipelineHandler + ) + <# It needs to be this way incase of different arguments being passed to different machines + [array]ServersWithArguments + [string]ServerName + [object]ArgumentList #customized for your scriptblock + #> + + Function Wait-JobsCompleted { + Write-Verbose "Calling Wait-JobsCompleted" + [System.Diagnostics.Stopwatch]$timer = [System.Diagnostics.Stopwatch]::StartNew() + # Data returned is a Hash Table that matches to the Server the Script Block ran against + $returnData = @{} + do { + $completedJobs = Get-Job | Where-Object { $_.State -ne "Running" } + if ($null -eq $completedJobs) { + Start-Sleep 1 + continue + } + + foreach ($job in $completedJobs) { + $jobName = $job.Name + Write-Verbose "Job $($job.Name) received. State: $($job.State) | HasMoreData: $($job.HasMoreData)" + if ($NeedReturnData -eq $false -and $DisplayReceiveJob -eq $false -and $job.HasMoreData -eq $true) { + Write-Verbose "This job has data and you provided you didn't want to return it or display it." + } + $receiveJob = Receive-Job $job + Remove-Job $job + if ($null -eq $receiveJob) { + Write-Verbose "Job $jobName didn't have any receive job data" + } + + # If more things are added to the pipeline than just the desired result (like custom Write-Verbose data to the pipeline) + # The caller needs to handle this by having a custom scriptblock to process the data + # Then return the desired result back + if ($null -ne $RemotePipelineHandler -and $receiveJob) { + Write-Verbose "Starting to call RemotePipelineHandler" + $returnJobData = & $RemotePipelineHandler $receiveJob + Write-Verbose "Finished RemotePipelineHandler" + if ($null -ne $returnJobData) { + $returnData.Add($jobName, $returnJobData) + } else { + Write-Verbose "Nothing came back from the RemotePipelineHandler" + } + } elseif ($NeedReturnData) { + $returnData.Add($jobName, $receiveJob) + } + } + } while ($true -eq (Get-Job)) + $timer.Stop() + Write-Verbose "Waiting for jobs to complete took $($timer.Elapsed.TotalSeconds) seconds" + if ($NeedReturnData) { + return $returnData + } + return $null + } + + [System.Diagnostics.Stopwatch]$timerMain = [System.Diagnostics.Stopwatch]::StartNew() + Write-Verbose "Calling Start-JobManager" + Write-Verbose "Passed: [bool]DisplayReceiveJob: $DisplayReceiveJob | [string]JobBatchName: $JobBatchName | [bool]NeedReturnData:$NeedReturnData" + + foreach ($serverObject in $ServersWithArguments) { + $server = $serverObject.ServerName + $argumentList = $serverObject.ArgumentList + Write-Verbose "Starting job on server $server" + Invoke-Command -ComputerName $server -ScriptBlock $ScriptBlock -ArgumentList $argumentList -AsJob -JobName $server | Out-Null + } + + $data = Wait-JobsCompleted + $timerMain.Stop() + Write-Verbose "Exiting: Start-JobManager | Time in Start-JobManager: $($timerMain.Elapsed.TotalSeconds) seconds" + if ($NeedReturnData) { + return $data + } + return $null +} diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Test-DiskSpace.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Test-DiskSpace.ps1 index 674c7a0fcb..82fbcb55a0 100644 --- a/Diagnostics/ExchangeLogCollector/Helpers/Test-DiskSpace.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Test-DiskSpace.ps1 @@ -1,15 +1,21 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Add-ScriptBlockInjection.ps1 +. $PSScriptRoot\Enter-YesNoLoopAction.ps1 +. $PSScriptRoot\PipelineFunctions.ps1 +. $PSScriptRoot\Start-JobManager.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\Get-FreeSpace.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Invoke-CatchBlockActions.ps1 Function Test-DiskSpace { param( [Parameter(Mandatory = $true)][array]$Servers, [Parameter(Mandatory = $true)][string]$Path, [Parameter(Mandatory = $true)][int]$CheckSize ) - Write-ScriptDebug("Function Enter: Test-DiskSpace") - Write-ScriptDebug("Passed: [string]Path: {0} | [int]CheckSize: {1}" -f $Path, $CheckSize) - Write-ScriptHost -WriteString ("Checking the free space on the servers before collecting the data...") -ShowServer $false + Write-Verbose("Function Enter: Test-DiskSpace") + Write-Verbose("Passed: [string]Path: {0} | [int]CheckSize: {1}" -f $Path, $CheckSize) + Write-Host "Checking the free space on the servers before collecting the data..." if (-not ($Path.EndsWith("\"))) { $Path = "{0}\" -f $Path } @@ -20,20 +26,20 @@ Function Test-DiskSpace { [Parameter(Mandatory = $true)][int]$FreeSpace, [Parameter(Mandatory = $true)][int]$CheckSize ) - Write-ScriptDebug("Calling Test-ServerDiskSpace") - Write-ScriptDebug("Passed: [string]Server: {0} | [int]FreeSpace: {1} | [int]CheckSize: {2}" -f $Server, $FreeSpace, $CheckSize) + Write-Verbose("Calling Test-ServerDiskSpace") + Write-Verbose("Passed: [string]Server: {0} | [int]FreeSpace: {1} | [int]CheckSize: {2}" -f $Server, $FreeSpace, $CheckSize) if ($FreeSpace -gt $CheckSize) { - Write-ScriptHost -WriteString ("[Server: {0}] : We have more than {1} GB of free space." -f $Server, $CheckSize) -ShowServer $false + Write-Host "[Server: $Server] : We have more than $CheckSize GB of free space." return $true } else { - Write-ScriptHost -WriteString ("[Server: {0}] : We have less than {1} GB of free space." -f $Server, $CheckSize) -ShowServer $false + Write-Host "[Server: $Server] : We have less than $CheckSize GB of free space." return $false } } if ($Servers.Count -eq 1 -and $Servers[0] -eq $env:COMPUTERNAME) { - Write-ScriptDebug("Local server only check. Not going to invoke Start-JobManager") + Write-Verbose("Local server only check. Not going to invoke Start-JobManager") $freeSpace = Get-FreeSpace -FilePath $Path if (Test-ServerDiskSpace -Server $Servers[0] -FreeSpace $freeSpace -CheckSize $CheckSize) { return $Servers[0] @@ -44,20 +50,24 @@ Function Test-DiskSpace { $serverArgs = @() foreach ($server in $Servers) { - $obj = New-Object PSCustomObject - $obj | Add-Member -MemberType NoteProperty -Name ServerName -Value $server - $obj | Add-Member -MemberType NoteProperty -Name ArgumentList -Value $Path - $serverArgs += $obj + $serverArgs += [PSCustomObject]@{ + ServerName = $server + ArgumentList = $Path + } } - Write-ScriptDebug("Getting Get-FreeSpace string to create Script Block") - $getFreeSpaceString = (${Function:Get-FreeSpace}).ToString().Replace("#Function Version", (Get-WritersToAddToScriptBlock)) - Write-ScriptDebug("Creating Script Block") + Write-Verbose("Getting Get-FreeSpace string to create Script Block") + SetWriteRemoteVerboseAction "New-VerbosePipelineObject" + $getFreeSpaceString = Add-ScriptBlockInjection -PrimaryScriptBlock ${Function:Get-FreeSpace} ` + -IncludeScriptBlock @(${Function:Write-Verbose}, ${Function:New-PipelineObject}, ${Function:New-VerbosePipelineObject}) ` + -IncludeUsingParameter "WriteRemoteVerboseDebugAction" ` + -CatchActionFunction ${Function:Invoke-CatchBlockActions} + Write-Verbose("Creating Script Block") $getFreeSpaceScriptBlock = [scriptblock]::Create($getFreeSpaceString) $serversData = Start-JobManager -ServersWithArguments $serverArgs -ScriptBlock $getFreeSpaceScriptBlock ` -NeedReturnData $true ` - -DisplayReceiveJobInCorrectFunction $true ` - -JobBatchName "Getting the free space for test disk space" + -JobBatchName "Getting the free space for test disk space" ` + -RemotePipelineHandler ${Function:Invoke-PipelineHandler} $passedServers = @() foreach ($server in $Servers) { @@ -68,17 +78,17 @@ Function Test-DiskSpace { } if ($passedServers.Count -eq 0) { - Write-ScriptHost -WriteString("Looks like all the servers didn't pass the disk space check.") -ShowServer $false - Write-ScriptHost -WriteString("Because there are no servers left, we will stop the script.") -ShowServer $false + Write-Host "Looks like all the servers didn't pass the disk space check." + Write-Host "Because there are no servers left, we will stop the script." exit } elseif ($passedServers.Count -ne $Servers.Count) { - Write-ScriptHost -WriteString ("Looks like all the servers didn't pass the disk space check.") -ShowServer $false - Write-ScriptHost -WriteString ("We will only collect data from these servers: ") -ShowServer $false + Write-Host "Looks like all the servers didn't pass the disk space check." + Write-Host "We will only collect data from these servers: " foreach ($svr in $passedServers) { - Write-ScriptHost -ShowServer $false -WriteString ("{0}" -f $svr) + Write-Host $svr } Enter-YesNoLoopAction -Question "Are yu sure you want to continue?" -YesAction {} -NoAction { exit } } - Write-ScriptDebug("Function Exit: Test-DiskSpace") + Write-Verbose("Function Exit: Test-DiskSpace") return $passedServers } diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Test-NoSwitchesProvided.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Test-NoSwitchesProvided.ps1 index 8bdbd5dc7b..13843e6966 100644 --- a/Diagnostics/ExchangeLogCollector/Helpers/Test-NoSwitchesProvided.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Test-NoSwitchesProvided.ps1 @@ -1,6 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Enter-YesNoLoopAction.ps1 Function Test-NoSwitchesProvided { if ($EWSLogs -or $IISLogs -or @@ -32,7 +33,7 @@ Function Test-NoSwitchesProvided { ) { return } else { - Write-ScriptHost -WriteString "`r`nWARNING: Doesn't look like any parameters were provided, are you sure you are running the correct command? This is ONLY going to collect the Application and System Logs." -ShowServer $false -ForegroundColor "Yellow" + Write-Host "`r`nWARNING: Doesn't look like any parameters were provided, are you sure you are running the correct command? This is ONLY going to collect the Application and System Logs." -ForegroundColor "Yellow" Enter-YesNoLoopAction -Question "Would you like to continue?" -YesAction { Write-Host "Okay moving on..." } -NoAction { exit } } } diff --git a/Diagnostics/ExchangeLogCollector/Helpers/Test-RemoteExecutionOfServers.ps1 b/Diagnostics/ExchangeLogCollector/Helpers/Test-RemoteExecutionOfServers.ps1 index e05501fcd8..ce4986690b 100644 --- a/Diagnostics/ExchangeLogCollector/Helpers/Test-RemoteExecutionOfServers.ps1 +++ b/Diagnostics/ExchangeLogCollector/Helpers/Test-RemoteExecutionOfServers.ps1 @@ -1,29 +1,31 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Enter-YesNoLoopAction.ps1 +. $PSScriptRoot\Test-DiskSpace.ps1 Function Test-RemoteExecutionOfServers { param( [Parameter(Mandatory = $true)][Array]$ServerList ) - Write-ScriptDebug("Function Enter: Test-RemoteExecutionOfServers") - Write-ScriptHost -WriteString "Checking to see if the servers are up in this list:" -ShowServer $false - $ServerList | ForEach-Object { Write-ScriptHost -WriteString $_ -ShowServer $false } + Write-Verbose("Function Enter: Test-RemoteExecutionOfServers") + Write-Host "Checking to see if the servers are up in this list:" + $ServerList | ForEach-Object { Write-Host $_ } #Going to just use Invoke-Command to see if the servers are up. As ICMP might be disabled in the environment. - Write-ScriptHost " " -ShowServer $false - Write-ScriptHost -WriteString "For all the servers in the list, checking to see if Invoke-Command will work against them." -ShowServer $false + Write-Host "" + Write-Host "For all the servers in the list, checking to see if Invoke-Command will work against them." #shouldn't need to test if they are Exchange servers, as we should be doing that locally as well. $validServers = @() foreach ($server in $ServerList) { try { - Write-ScriptHost -WriteString ("Checking Server {0}....." -f $server) -ShowServer $false -NoNewLine $true + Write-Host "Checking Server $server....." -NoNewline Invoke-Command -ComputerName $server -ScriptBlock { Get-Process | Out-Null } -ErrorAction Stop #if that doesn't fail, we should be okay to add it to the working list - Write-ScriptHost -WriteString ("Passed") -ShowServer $false -ForegroundColor "Green" + Write-Host "Passed" -ForegroundColor "Green" $validServers += $server } catch { - Write-ScriptHost -WriteString "Failed" -ShowServer $false -ForegroundColor "Red" - Write-ScriptHost -WriteString ("Removing Server {0} from the list to collect data from" -f $server) -ShowServer $false + Write-Host "Failed" -ForegroundColor "Red" + Write-Host "Removing Server $server from the list to collect data from" Invoke-CatchBlockActions } } @@ -39,11 +41,11 @@ Function Test-RemoteExecutionOfServers { #Can't do this on a tools or remote shell if ($Script:LocalExchangeShell.ToolsOnly -or $Script:LocalExchangeShell.RemoteShell) { - Write-ScriptHost -WriteString "Failed to invoke against the machines to do remote collection from a tools box or a remote machine." -ForegroundColor "Red" + Write-Host "Failed to invoke against the machines to do remote collection from a tools box or a remote machine." -ForegroundColor "Red" exit } - Write-ScriptHost -ShowServer $false -WriteString ("Failed to do remote collection for all the servers in the list...") -ForegroundColor "Yellow" + Write-Host "Failed to do remote collection for all the servers in the list..." -ForegroundColor "Yellow" if ((Enter-YesNoLoopAction -Question "Do you want to collect from the local server only?" -YesAction { return $true } -NoAction { return $false })) { $validServers = @($env:COMPUTERNAME) @@ -53,11 +55,11 @@ Function Test-RemoteExecutionOfServers { #want to test local server's free space first before moving to just collecting the data if ($null -eq (Test-DiskSpace -Servers $validServers -Path $FilePath -CheckSize $Script:StandardFreeSpaceInGBCheckSize)) { - Write-ScriptHost -ShowServer $false -WriteString ("Failed to have enough space available locally. We can't continue with the data collection") -ForegroundColor "Yellow" + Write-Host "Failed to have enough space available locally. We can't continue with the data collection" -ForegroundColor "Yellow" exit } } - Write-ScriptDebug("Function Exit: Test-RemoteExecutionOfServers") + Write-Verbose("Function Exit: Test-RemoteExecutionOfServers") return $validServers } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Add-ServerNameToFileName.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Add-ServerNameToFileName.ps1 index 4434e2ad2d..c7dcc521c3 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Add-ServerNameToFileName.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Add-ServerNameToFileName.ps1 @@ -5,10 +5,10 @@ Function Add-ServerNameToFileName { param( [Parameter(Mandatory = $true)][string]$FilePath ) - Write-ScriptDebug("Calling: Add-ServerNameToFileName") - Write-ScriptDebug("Passed: [string]FilePath: {0}" -f $FilePath) + Write-Verbose("Calling: Add-ServerNameToFileName") + Write-Verbose("Passed: [string]FilePath: {0}" -f $FilePath) $fileName = "{0}_{1}" -f $env:COMPUTERNAME, ($name = $FilePath.Substring($FilePath.LastIndexOf("\") + 1)) $filePathWithServerName = $FilePath.Replace($name, $fileName) - Write-ScriptDebug("Returned: {0}" -f $filePathWithServerName) + Write-Verbose("Returned: {0}" -f $filePathWithServerName) return $filePathWithServerName } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ClusterNodeFileVersions.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ClusterNodeFileVersions.ps1 similarity index 86% rename from Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ClusterNodeFileVersions.ps1 rename to Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ClusterNodeFileVersions.ps1 index 1fbfd156f5..4c41e644df 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ClusterNodeFileVersions.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ClusterNodeFileVersions.ps1 @@ -1,8 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/ComputerInformation/Get-ClusterNodeFileVersions/Get-ClusterNodeFileVersions.ps1 -#v21.01.22.2212 Function Get-ClusterNodeFileVersions { [CmdletBinding()] param( diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ExchangeInstallDirectory.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ExchangeInstallDirectory.ps1 new file mode 100644 index 0000000000..dddefba6e6 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ExchangeInstallDirectory.ps1 @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function Get-ExchangeInstallDirectory { + [CmdletBinding()] + param() + + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + + $installDirectory = [string]::Empty + if (Test-Path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup') { + Write-Verbose "Detected v14" + $installDirectory = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath + } elseif (Test-Path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\Setup') { + Write-Verbose "Detected v15" + $installDirectory = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\Setup).MsiInstallPath + } else { + Write-Host "Something went wrong trying to find Exchange Install path on this server: $env:COMPUTERNAME" + } + + Write-Verbose "Returning: $installDirectory" + + return $installDirectory +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-FreeSpace.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-FreeSpace.ps1 new file mode 100644 index 0000000000..6e37fcf831 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-FreeSpace.ps1 @@ -0,0 +1,63 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function Get-FreeSpace { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWMICmdlet', '', Justification = 'Different types returned')] + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)][ValidateScript( { $_.ToString().EndsWith("\") })][string]$FilePath + ) + + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + Write-Verbose "Passed: [string]FilePath: $FilePath" + + $drivesList = Get-WmiObject Win32_Volume -Filter "drivetype = 3" + $testPath = $FilePath + $freeSpaceSize = -1 + while ($true) { + if ($testPath -eq [string]::Empty) { + Write-Host "Unable to fine a drive that matches the file path: $FilePath" + return $freeSpaceSize + } + Write-Verbose "Trying to find path that matches path: $testPath" + foreach ($drive in $drivesList) { + if ($drive.Name -eq $testPath) { + Write-Verbose "Found a match" + $freeSpaceSize = $drive.FreeSpace / 1GB + Write-Verbose "Have $freeSpaceSize`GB of Free Space" + return $freeSpaceSize + } + Write-Verbose "Drive name: '$($drive.Name)' didn't match" + } + + $itemTarget = [string]::Empty + if ((Test-Path $testPath)) { + $item = Get-Item $testPath + if ($item.Target -like "Volume{*}\") { + Write-Verbose "File Path appears to be a mount point target: $($item.Target)" + $itemTarget = $item.Target + } else { + Write-Verbose "Path didn't appear to be a mount point target" + } + } else { + Write-Verbose "Path isn't a true path yet." + } + + if ($itemTarget -ne [string]::Empty) { + foreach ($drive in $drivesList) { + if ($drive.DeviceID.Contains($itemTarget)) { + $freeSpaceSize = $drive.FreeSpace / 1GB + Write-Verbose "Have $freeSpaceSize`GB of Free Space" + return $freeSpaceSize + } + Write-Verbose "DeviceID didn't appear to match: $($drive.DeviceID)" + } + if ($freeSpaceSize -eq -1) { + Write-Host "Unable to fine a drive that matches the file path: $FilePath" + Write-Host "This shouldn't have happened." + return $freeSpaceSize + } + } + $testPath = $testPath.Substring(0, $testPath.LastIndexOf("\", $testPath.Length - 2) + 1) + } +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-IISLogDirectory.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-IISLogDirectory.ps1 index 0436539eae..7d05a213af 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-IISLogDirectory.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-IISLogDirectory.ps1 @@ -1,15 +1,16 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Test-CommandExists.ps1 Function Get-IISLogDirectory { - Write-ScriptDebug("Function Enter: Get-IISLogDirectory") + Write-Verbose("Function Enter: Get-IISLogDirectory") Function Get-IISDirectoryFromGetWebSite { - Write-ScriptDebug("Get-WebSite command exists") + Write-Verbose("Get-WebSite command exists") return Get-WebSite | ForEach-Object { $logFile = "$($_.LogFile.Directory)\W3SVC$($_.id)".Replace("%SystemDrive%", $env:SystemDrive) - Write-ScriptDebug("Found Directory: $logFile") + Write-Verbose("Found Directory: $logFile") return $logFile } } @@ -19,9 +20,9 @@ Function Get-IISLogDirectory { } else { #May need to load the module try { - Write-ScriptDebug("Going to attempt to load the WebAdministration Module") + Write-Verbose("Going to attempt to load the WebAdministration Module") Import-Module WebAdministration -ErrorAction Stop - Write-ScriptDebug("Successful loading the module") + Write-Verbose("Successful loading the module") if ((Test-CommandExists -command "Get-WebSite")) { [array]$iisLogDirectory = Get-IISDirectoryFromGetWebSite @@ -29,10 +30,10 @@ Function Get-IISLogDirectory { } catch { Invoke-CatchBlockActions [array]$iisLogDirectory = "C:\inetpub\logs\LogFiles\" #Default location for IIS Logs - Write-ScriptDebug("Get-WebSite command doesn't exists. Set IISLogDirectory to: {0}" -f $iisLogDirectory) + Write-Verbose("Get-WebSite command doesn't exists. Set IISLogDirectory to: {0}" -f $iisLogDirectory) } } - Write-ScriptDebug("Function Exit: Get-IISLogDirectory") + Write-Verbose("Function Exit: Get-IISLogDirectory") return $iisLogDirectory } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ItemsSize.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ItemsSize.ps1 index 7d9dc02ef6..d7751b869e 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ItemsSize.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-ItemsSize.ps1 @@ -5,19 +5,19 @@ Function Get-ItemsSize { param( [Parameter(Mandatory = $true)][array]$FilePaths ) - Write-ScriptDebug("Calling: Get-ItemsSize") + Write-Verbose("Calling: Get-ItemsSize") $totalSize = 0 $hashSizes = @{} foreach ($file in $FilePaths) { if (Test-Path $file) { $totalSize += ($fileSize = (Get-Item $file).Length) - Write-ScriptDebug("File: {0} | Size: {1} MB" -f $file, ($fileSizeMB = $fileSize / 1MB)) + Write-Verbose("File: {0} | Size: {1} MB" -f $file, ($fileSizeMB = $fileSize / 1MB)) $hashSizes.Add($file, ("{0}" -f $fileSizeMB)) } else { - Write-ScriptDebug("File no longer exists: {0}" -f $file) + Write-Verbose("File no longer exists: {0}" -f $file) } } Set-Variable -Name ItemSizesHashed -Value $hashSizes -Scope Script - Write-ScriptDebug("Returning: {0}" -f $totalSize) + Write-Verbose("Returning: {0}" -f $totalSize) return $totalSize } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-StringDataForNotEnoughFreeSpace.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-StringDataForNotEnoughFreeSpace.ps1 index a91ffd6360..0ba1e9f1eb 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-StringDataForNotEnoughFreeSpace.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Get-StringDataForNotEnoughFreeSpace.ps1 @@ -5,7 +5,7 @@ Function Get-StringDataForNotEnoughFreeSpaceFile { param( [Parameter(Mandatory = $true)][hashtable]$hasher ) - Write-ScriptDebug("Calling: Get-StringDataForNotEnoughFreeSpaceFile") + Write-Verbose("Calling: Get-StringDataForNotEnoughFreeSpaceFile") $reader = [string]::Empty $totalSizeMB = 0 foreach ($key in $hasher.Keys) { diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Compress-Folder.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Compress-Folder.ps1 new file mode 100644 index 0000000000..e5a78819ad --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Compress-Folder.ps1 @@ -0,0 +1,106 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function Compress-Folder { + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Position = 1)][string]$Folder, + [Parameter(Position = 2)][bool]$IncludeMonthDay = $false, + [Parameter(Position = 3)][bool]$IncludeDisplayZipping = $true, + [Parameter(Position = 4)][bool]$ReturnCompressedLocation = $false + ) + + Function Get-DirectorySize { + param( + [Parameter(Mandatory = $true)][string]$Directory, + [Parameter(Mandatory = $false)][bool]$IsCompressed = $false + ) + $itemSize = 0 + if ($IsCompressed) { + $itemSize = (Get-Item $Directory).Length + } else { + $childItems = Get-ChildItem $Directory -Recurse | Where-Object { -not($_.Mode.StartsWith("d-")) } + foreach ($item in $childItems) { + $itemSize += $item.Length + } + } + return $itemSize + } + + if ($Folder.EndsWith("\")) { + $Folder = $Folder.TrimEnd("\") + } + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + Write-Verbose "Passed - [string]Folder: $Folder | [bool]IncludeDisplayZipping: $IncludeDisplayZipping | [bool]ReturnCompressedLocation: $ReturnCompressedLocation" + + $compressedLocation = [string]::Empty + if (Test-Path $Folder) { + + $assemblies = [Appdomain]::CurrentDomain.GetAssemblies() + $successful = $false + foreach ($assembly in $assemblies) { + if ($assembly.Location -like "*System.IO.Compression.Filesystem*") { + $successful = $true + break + } + } + + Write-Verbose "Found IO Compression loaded: $successful" + + if ($successful -eq $false) { + # Try to load the IO Compression + $loadedIOCompression = $false + try { + Add-Type -AssemblyName System.IO.Compression.Filesystem -ErrorAction Stop + $loadedIOCompression = $true + } catch { + Write-Host "Failed to load .NET Compression assembly. Unable to compress up the data." + } + + if ($loadedIOCompression -eq $false) { + Write-Verbose "Unable to compress folder $Folder" + Write-Verbose "Unable to enable IO compression on this system" + return $null + } + } + + if ($IncludeMonthDay) { + $zipFolderNoEXT = "{0}-{1}" -f $Folder, (Get-Date -Format Md) + } else { + $zipFolderNoEXT = $Folder + } + Write-Verbose "[string]zipFolderNoEXT: $zipFolderNoEXT" + $zipFolder = "{0}.zip" -f $zipFolderNoEXT + if (Test-Path $zipFolder) { + [int]$i = 1 + do { + $zipFolder = "{0}-{1}.zip" -f $zipFolderNoEXT, $i + $i++ + }while (Test-Path $zipFolder) + } + Write-Verbose "Using Zip Folder Path: $zipFolder" + + if ($IncludeDisplayZipping) { + Write-Host "Compressing Folder $Folder" + } + $sizeBytesBefore = Get-DirectorySize -Directory $Folder + $timer = [System.Diagnostics.Stopwatch]::StartNew() + [System.IO.Compression.ZipFile]::CreateFromDirectory($Folder, $zipFolder) + $timer.Stop() + $sizeBytesAfter = Get-DirectorySize -Directory $zipFolder -IsCompressed $true + Write-Verbose ("Compressing directory size of {0} MB down to the size of {1} MB took {2} seconds." -f ($sizeBytesBefore / 1MB), ($sizeBytesAfter / 1MB), $timer.Elapsed.TotalSeconds) + if ((Test-Path -Path $zipFolder)) { + Write-Verbose "Compress successful, removing folder." + Remove-Item $Folder -Force -Recurse + } + if ($ReturnCompressedLocation) { + $compressedLocation = $zipFolder + } + } else { + Write-Host "Failed to find the folder $Folder" + } + + Write-Verbose "Returning: $compressedLocation" + return $compressedLocation +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-BulkItems.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-BulkItems.ps1 index a2e9ab134a..8cc3079425 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-BulkItems.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-BulkItems.ps1 @@ -1,6 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\New-Folder.ps1 +. $PSScriptRoot\..\Get-StringDataForNotEnoughFreeSpace.ps1 +. $PSScriptRoot\..\Test-FreeSpace.ps1 Function Copy-BulkItems { param( [string]$CopyToLocation, @@ -15,7 +18,7 @@ Function Copy-BulkItems { Copy-Item -Path $item -Destination $CopyToLocation -ErrorAction SilentlyContinue } } else { - Write-ScriptHost("Not enough free space to copy over this data set.") + Write-Host "Not enough free space to copy over this data set." New-Item -Path ("{0}\NotEnoughFreeSpace.txt" -f $CopyToLocation) -ItemType File -Value (Get-StringDataForNotEnoughFreeSpaceFile -hasher $Script:ItemSizesHashed) | Out-Null } } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-FullLogFullPathRecurse.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-FullLogFullPathRecurse.ps1 index 965c9b0c74..4893ce07fd 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-FullLogFullPathRecurse.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-FullLogFullPathRecurse.ps1 @@ -1,13 +1,16 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\New-Folder.ps1 +. $PSScriptRoot\..\Get-StringDataForNotEnoughFreeSpace.ps1 +. $PSScriptRoot\..\Test-FreeSpace.ps1 Function Copy-FullLogFullPathRecurse { param( [Parameter(Mandatory = $true)][string]$LogPath, [Parameter(Mandatory = $true)][string]$CopyToThisLocation ) - Write-ScriptDebug("Function Enter: Copy-FullLogFullPathRecurse") - Write-ScriptDebug("Passed: [string]LogPath: {0} | [string]CopyToThisLocation: {1}" -f $LogPath, $CopyToThisLocation) + Write-Verbose("Function Enter: Copy-FullLogFullPathRecurse") + Write-Verbose("Passed: [string]LogPath: {0} | [string]CopyToThisLocation: {1}" -f $LogPath, $CopyToThisLocation) New-Folder -NewFolder $CopyToThisLocation -IncludeDisplayCreate $true if (Test-Path $LogPath) { $childItems = Get-ChildItem $LogPath -Recurse @@ -24,16 +27,16 @@ Function Copy-FullLogFullPathRecurse { Copy-Item $LogPath\* $CopyToThisLocation -Recurse -ErrorAction SilentlyContinue Invoke-ZipFolder $CopyToThisLocation } else { - Write-ScriptDebug("Not going to copy over this set of data due to size restrictions.") + Write-Verbose("Not going to copy over this set of data due to size restrictions.") New-Item -Path ("{0}\NotEnoughFreeSpace.txt" -f $CopyToThisLocation) -ItemType File -Value (Get-StringDataForNotEnoughFreeSpaceFile -hasher $Script:ItemSizesHashed) | Out-Null } } else { - Write-ScriptHost("No data at path '{0}'. Unable to copy this data." -f $LogPath) + Write-Host "No data at path '$LogPath'. Unable to copy this data." New-Item -Path ("{0}\NoDataDetected.txt" -f $CopyToThisLocation) -ItemType File -Value $LogPath | Out-Null } } else { - Write-ScriptHost("No Folder at {0}. Unable to copy this data." -f $LogPath) + Write-Host "No Folder at $LogPath. Unable to copy this data." New-Item -Path ("{0}\NoFolderDetected.txt" -f $CopyToThisLocation) -ItemType File -Value $LogPath | Out-Null } - Write-ScriptDebug("Function Exit: Copy-FullLogFullPathRecurse") + Write-Verbose("Function Exit: Copy-FullLogFullPathRecurse") } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogmanData.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogmanData.ps1 index 0e6f3bc918..60ea4506e9 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogmanData.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogmanData.ps1 @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Copy-BulkItems.ps1 +. $PSScriptRoot\New-Folder.ps1 Function Copy-LogmanData { param( [Parameter(Mandatory = $true)]$ObjLogman @@ -22,11 +24,11 @@ Function Copy-LogmanData { $filterDate = $objLogman.StartDate $copyFromDate = [DateTime]::Now - $PassedInfo.TimeSpan - Write-ScriptDebug("Copy From Date: {0}" -f $filterDate) + Write-Verbose("Copy From Date: {0}" -f $filterDate) if ([DateTime]$filterDate -lt [DateTime]$copyFromDate) { $filterDate = $copyFromDate - Write-ScriptDebug("Updating Copy From Date to: '{0}'" -f $filterDate) + Write-Verbose("Updating Copy From Date to: '{0}'" -f $filterDate) } $childItems = Get-ChildItem $strDirectory -Recurse | Where-Object { ($_.Name -like $wildExt) -and ($_.CreationTime -ge $filterDate) } @@ -38,8 +40,8 @@ Function Copy-LogmanData { Copy-BulkItems -CopyToLocation $copyTo -ItemsToCopyLocation $items Invoke-ZipFolder -Folder $copyTo } else { - Write-ScriptHost -WriteString ("Failed to find any files in the directory: '{0}' that was greater than or equal to this time: {1}" -f $strDirectory, $filterDate) -ForegroundColor "Yellow" - Write-ScriptHost -WriteString ("Going to try to see if there are any files in this directory for you..." ) -NoNewline $true + Write-Host "Failed to find any files in the directory: '$strDirectory' that was greater than or equal to this time: $filterDate" -ForegroundColor "Yellow" + Write-Host "Going to try to see if there are any files in this directory for you..." -NoNewline $files = Get-ChildItem $strDirectory -Recurse | Where-Object { $_.Name -like $wildExt } if ($null -ne $files) { #only want to get latest data @@ -56,13 +58,13 @@ Function Copy-LogmanData { Invoke-ZipFolder -Folder $copyTo } } else { - Write-ScriptHost -WriteString ("Failed to find any files in the directory: '{0}'" -f $strDirectory) -ForegroundColor "Yellow" + Write-Host "Failed to find any files in the directory: '$strDirectory'" -ForegroundColor "Yellow" $tempFile = $copyTo + "\NoFiles.txt" New-Item $tempFile -ItemType File -Value $strDirectory | Out-Null } } } else { - Write-ScriptHost -WriteString ("Doesn't look like this Directory is valid. {0}" -f $strDirectory) -ForegroundColor "Yellow" + Write-Host "Doesn't look like this Directory is valid. $strDirectory" -ForegroundColor "Yellow" $tempFile = $copyTo + "\NotValidDirectory.txt" New-Item $tempFile -ItemType File -Value $strDirectory | Out-Null } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogsBasedOnTime.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogsBasedOnTime.ps1 index 2138f11364..7e6fba00f4 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogsBasedOnTime.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Copy-LogsBasedOnTime.ps1 @@ -1,16 +1,18 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Copy-BulkItems.ps1 +. $PSScriptRoot\New-Folder.ps1 Function Copy-LogsBasedOnTime { param( [Parameter(Mandatory = $false)][string]$LogPath, [Parameter(Mandatory = $true)][string]$CopyToThisLocation ) - Write-ScriptDebug("Function Enter: Copy-LogsBasedOnTime") - Write-ScriptDebug("Passed: [string]LogPath: {0} | [string]CopyToThisLocation: {1}" -f $LogPath, $CopyToThisLocation) + Write-Verbose("Function Enter: Copy-LogsBasedOnTime") + Write-Verbose("Passed: [string]LogPath: {0} | [string]CopyToThisLocation: {1}" -f $LogPath, $CopyToThisLocation) if ([string]::IsNullOrEmpty($LogPath)) { - Write-ScriptDebug("Failed to provide a valid log path to copy.") + Write-Verbose("Failed to provide a valid log path to copy.") return } @@ -21,7 +23,7 @@ Function Copy-LogsBasedOnTime { [Parameter(Mandatory = $true)][string]$CopyFromLocation, [Parameter(Mandatory = $true)][string]$CopyToLocation ) - Write-ScriptHost -WriteString ("It doesn't look like you have any data in this location {0}." -f $CopyFromLocation) -ForegroundColor "Yellow" + Write-Host "It doesn't look like you have any data in this location $CopyFromLocation." -ForegroundColor "Yellow" #Going to place a file in this location so we know what happened $tempFile = $CopyToLocation + "\NoFilesDetected.txt" New-Item $tempFile -ItemType File -Value $LogPath | Out-Null @@ -29,12 +31,12 @@ Function Copy-LogsBasedOnTime { } $copyFromDate = [DateTime]::Now - $PassedInfo.TimeSpan - Write-ScriptDebug("Copy From Date: {0}" -f $copyFromDate) + Write-Verbose("Copy From Date: {0}" -f $copyFromDate) $skipCopy = $false if (!(Test-Path $LogPath)) { #if the directory isn't there, we need to handle it NoFilesInLocation -CopyFromLocation $LogPath -CopyToLocation $CopyToThisLocation - Write-ScriptDebug("Function Exit: Copy-LogsBasedOnTime") + Write-Verbose("Function Exit: Copy-LogsBasedOnTime") return } #We are not copying files recurse so we need to not include possible directories or we will throw an error @@ -47,11 +49,11 @@ Function Copy-LogsBasedOnTime { 1. We don't have any files in the timeframe request in the directory that we are looking at 2. We have sub directories that we need to look into and look at those files (Only if we don't have files in the currently location so we aren't pulling files like the index files from message tracking) #> - Write-ScriptDebug("Copy-LogsBasedOnTime: Failed to find any logs in the directory provided, need to do a deeper look to find some logs that we want.") + Write-Verbose("Copy-LogsBasedOnTime: Failed to find any logs in the directory provided, need to do a deeper look to find some logs that we want.") $allFiles = Get-ChildItem $LogPath | Sort-Object LastWriteTime -Descending - Write-ScriptDebug("Displaying all items in the directory: {0}" -f $LogPath) + Write-Verbose("Displaying all items in the directory: {0}" -f $LogPath) foreach ($file in $allFiles) { - Write-ScriptDebug("File Name: {0} Last Write Time: {1}" -f $file.Name, $file.LastWriteTime) + Write-Verbose("File Name: {0} Last Write Time: {1}" -f $file.Name, $file.LastWriteTime) } #Let's see if we have any files in this location while having directories @@ -70,14 +72,14 @@ Function Copy-LogsBasedOnTime { if ($null -eq $files) { NoFilesInLocation -CopyFromLocation $newLogPath -CopyToLocation $newCopyToThisLocation } else { - Write-ScriptDebug("Found {0} number of files at the location {1}" -f $files.Count, $newLogPath) + Write-Verbose("Found {0} number of files at the location {1}" -f $files.Count, $newLogPath) $filesFullPath = @() $files | ForEach-Object { $filesFullPath += $_.VersionInfo.FileName } Copy-BulkItems -CopyToLocation $newCopyToThisLocation -ItemsToCopyLocation $filesFullPath Invoke-ZipFolder -Folder $newCopyToThisLocation } } - Write-ScriptDebug("Function Exit: Copy-LogsBasedOnTime") + Write-Verbose("Function Exit: Copy-LogsBasedOnTime") return } @@ -90,7 +92,7 @@ Function Copy-LogsBasedOnTime { NoFilesInLocation -CopyFromLocation $LogPath -CopyToLocation $CopyToThisLocation } } - Write-ScriptDebug("Found {0} number of files at the location {1}" -f $Files.Count, $LogPath) + Write-Verbose("Found {0} number of files at the location {1}" -f $Files.Count, $LogPath) #ResetFiles to full path $filesFullPath = @() $files | ForEach-Object { $filesFullPath += $_.VersionInfo.FileName } @@ -99,5 +101,5 @@ Function Copy-LogsBasedOnTime { Copy-BulkItems -CopyToLocation $CopyToThisLocation -ItemsToCopyLocation $filesFullPath Invoke-ZipFolder -Folder $CopyToThisLocation } - Write-ScriptDebug("Function Exit: Copy-LogsBasedOnTime") + Write-Verbose("Function Exit: Copy-LogsBasedOnTime") } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Invoke-CatchBlockActions.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Invoke-CatchBlockActions.ps1 index 2081a1b795..ee3d344d6a 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Invoke-CatchBlockActions.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Invoke-CatchBlockActions.ps1 @@ -2,7 +2,7 @@ # Licensed under the MIT License. Function Invoke-CatchBlockActions { - Write-ScriptDebug -WriteString ("Error Exception: $($Error[0].Exception)") - Write-ScriptDebug -WriteString ("Error Stack: $($Error[0].ScriptStackTrace)") + Write-Verbose "Error Exception: $($Error[0].Exception)" + Write-Verbose "Error Stack: $($Error[0].ScriptStackTrace)" [array]$Script:ErrorsHandled += $Error[0] } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/New-Folder.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/New-Folder.ps1 new file mode 100644 index 0000000000..496839fe7a --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/New-Folder.ps1 @@ -0,0 +1,33 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function New-Folder { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Caller knows that this is an action')] + [CmdletBinding()] + param( + [Alias("NewFolder")] + [Parameter(Mandatory = $false)][array]$NewFolders, + [Parameter(Mandatory = $false)][bool]$IncludeDisplayCreate + ) + + if ($NewFolders.Count -gt 1) { + $verboseDisplayNewFolders = "Multiple ('{0}') Folders Passed" -f $NewFolders.Count + } else { + $verboseDisplayNewFolders = $NewFolders[0] + } + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + Write-Verbose "Passed: [string]NewFolders: $verboseDisplayNewFolders | [bool]IncludeDisplayCreate: $IncludeDisplayCreate" + + foreach ($newFolder in $NewFolders) { + if (-not (Test-Path -Path $newFolder)) { + if ($IncludeDisplayCreate) { + Write-Host "Creating Directory: $newFolder" + } + [System.IO.Directory]::CreateDirectory($newFolder) | Out-Null + } else { + if ($IncludeDisplayCreate) { + Write-Host "Directory $newFolder is already created!" + } + } + } +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataInfoToFile.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataInfoToFile.ps1 index 2fdd8d28d8..b20ff19756 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataInfoToFile.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataInfoToFile.ps1 @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Save-DataToFile.ps1 +. $PSScriptRoot\..\Add-ServerNameToFileName.ps1 Function Save-DataInfoToFile { param( [Parameter(Mandatory = $false)][object]$DataIn, @@ -11,7 +13,7 @@ Function Save-DataInfoToFile { [Parameter(Mandatory = $false)][bool]$AddServerName = $true ) [System.Diagnostics.Stopwatch]$timer = [System.Diagnostics.Stopwatch]::StartNew() - Write-ScriptDebug "Function Enter: Save-DataInfoToFile" + Write-Verbose "Function Enter: Save-DataInfoToFile" if ($AddServerName) { $SaveToLocation = Add-ServerNameToFileName $SaveToLocation @@ -19,5 +21,5 @@ Function Save-DataInfoToFile { Save-DataToFile -DataIn $DataIn -SaveToLocation $SaveToLocation -FormatList $FormatList -SaveTextFile $SaveTextFile -SaveXMLFile $SaveXMLFile $timer.Stop() - Write-ScriptDebug("Took {0} seconds to save out the data." -f $timer.Elapsed.TotalSeconds) + Write-Verbose("Took {0} seconds to save out the data." -f $timer.Elapsed.TotalSeconds) } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Save-DataToFile.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataToFile.ps1 similarity index 63% rename from Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Save-DataToFile.ps1 rename to Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataToFile.ps1 index 78c500e7f1..98ba6af3e1 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Save-DataToFile.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-DataToFile.ps1 @@ -1,8 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Save-DataToFile/Save-DataToFile.ps1 -#v21.01.22.2234 Function Save-DataToFile { [CmdletBinding()] param( @@ -12,14 +10,9 @@ Function Save-DataToFile { [Parameter(Mandatory = $false)][bool]$SaveTextFile = $true, [Parameter(Mandatory = $false)][bool]$SaveXMLFile = $true ) - #Function Version #v21.01.22.2234 - - Write-VerboseWriter("Calling: Save-DataToFile") - Write-VerboseWriter("Passed: [string]SaveToLocation: {0} | [bool]FormatList: {1} | [bool]SaveTextFile: {2} | [bool]SaveXMLFile: {3}" -f $SaveToLocation, - $FormatList, - $SaveTextFile, - $SaveXMLFile) + Write-Verbose "Calling: $($MyInvocation.MyCommand)" + Write-Verbose "Passed: [string]SaveToLocation: $SaveToLocation | [bool]FormatList: $FormatList | [bool]SaveTextFile: $SaveTextFile | [bool]SaveXMLFile: $SaveXMLFile" $xmlSaveLocation = "{0}.xml" -f $SaveToLocation $txtSaveLocation = "{0}.txt" -f $SaveToLocation @@ -36,7 +29,7 @@ Function Save-DataToFile { } } } else { - Write-VerboseWriter("DataIn was an empty string. Not going to save anything.") + Write-Verbose("DataIn was an empty string. Not going to save anything.") } - Write-VerboseWriter("Returning from Save-DataToFile") + Write-Verbose ("Returning from Save-DataToFile") } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-FailoverClusterInformation.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-FailoverClusterInformation.ps1 index 69cbc40d9e..62b99b15d8 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-FailoverClusterInformation.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-FailoverClusterInformation.ps1 @@ -1,51 +1,54 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\New-Folder.ps1 +. $PSScriptRoot\Save-DataInfoToFile.ps1 +. $PSScriptRoot\..\Get-ClusterNodeFileVersions.ps1 #Save out the failover cluster information for the local node, besides the event logs. Function Save-FailoverClusterInformation { - Write-ScriptDebug("Function Enter: Save-FailoverClusterInformation") + Write-Verbose("Function Enter: Save-FailoverClusterInformation") $copyTo = "$Script:RootCopyToDirectory\Cluster_Information" New-Folder -NewFolder $copyTo -IncludeDisplayCreate $true try { Save-DataInfoToFile -DataIn (Get-Cluster -ErrorAction Stop) -SaveToLocation "$copyTo\GetCluster" } catch { - Write-ScriptDebug "Failed to run Get-Cluster" + Write-Verbose "Failed to run Get-Cluster" Invoke-CatchBlockActions } try { Save-DataInfoToFile -DataIn (Get-ClusterGroup -ErrorAction Stop) -SaveToLocation "$copyTo\GetClusterGroup" } catch { - Write-ScriptDebug "Failed to run Get-ClusterGroup" + Write-Verbose "Failed to run Get-ClusterGroup" Invoke-CatchBlockActions } try { Save-DataInfoToFile -DataIn (Get-ClusterNode -ErrorAction Stop) -SaveToLocation "$copyTo\GetClusterNode" } catch { - Write-ScriptDebug "Failed to run Get-ClusterNode" + Write-Verbose "Failed to run Get-ClusterNode" Invoke-CatchBlockActions } try { Save-DataInfoToFile -DataIn (Get-ClusterNetwork -ErrorAction Stop) -SaveToLocation "$copyTo\GetClusterNetwork" } catch { - Write-ScriptDebug "Failed to run Get-ClusterNetwork" + Write-Verbose "Failed to run Get-ClusterNetwork" Invoke-CatchBlockActions } try { Save-DataInfoToFile -DataIn (Get-ClusterNetworkInterface -ErrorAction Stop) -SaveToLocation "$copyTo\GetClusterNetworkInterface" } catch { - Write-ScriptDebug "Failed to run Get-ClusterNetworkInterface" + Write-Verbose "Failed to run Get-ClusterNetworkInterface" Invoke-CatchBlockActions } try { Get-ClusterLog -Node $env:ComputerName -Destination $copyTo -ErrorAction Stop | Out-Null } catch { - Write-ScriptDebug "Failed to run Get-ClusterLog" + Write-Verbose "Failed to run Get-ClusterLog" Invoke-CatchBlockActions } @@ -54,7 +57,7 @@ Function Save-FailoverClusterInformation { Save-DataInfoToFile -DataIn $clusterNodeFileVersions -SaveToLocation "$copyTo\ClusterNodeFileVersions" -SaveTextFile $false Save-DataInfoToFile -DataIn ($clusterNodeFileVersions.Files.Values) -SaveToLocation "$copyTo\ClusterNodeFileVersions" -SaveXMLFile $false -FormatList $false } catch { - Write-ScriptDebug "Failed to run Get-ClusterNodeFileVersions" + Write-Verbose "Failed to run Get-ClusterNodeFileVersions" Invoke-CatchBlockActions } @@ -64,10 +67,10 @@ Function Save-FailoverClusterInformation { "To read the cluster hive. Run 'reg load HKLM\TempHive ClusterHive.hiv'. Then Open your regedit then go to HKLM:\TempHive to view the data." | Out-File -FilePath "$copyTo\ClusterHive_HowToRead.txt" } catch { - Write-ScriptDebug "Failed to get the Cluster Hive" + Write-Verbose "Failed to get the Cluster Hive" Invoke-CatchBlockActions } Invoke-ZipFolder -Folder $copyTo - Write-ScriptDebug "Function Exit: Save-FailoverClusterInformation" + Write-Verbose "Function Exit: Save-FailoverClusterInformation" } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExmonData.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExmonData.ps1 index 8a4fdd86c3..0c36cd0068 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExmonData.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExmonData.ps1 @@ -1,6 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\Logman\Get-LogmanData.ps1 Function Save-LogmanExmonData { Get-LogmanData -LogmanName $PassedInfo.ExmonLogmanName -ServerName $env:COMPUTERNAME } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExperfwizData.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExperfwizData.ps1 index cbc14b9b7a..e3c1579655 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExperfwizData.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-LogmanExperfwizData.ps1 @@ -1,6 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\Logman\Get-LogmanData.ps1 Function Save-LogmanExperfwizData { $PassedInfo.ExperfwizLogmanName | diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-ServerInfoData.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-ServerInfoData.ps1 index 68583cc67c..20f9f563d3 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-ServerInfoData.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-ServerInfoData.ps1 @@ -1,14 +1,18 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\New-Folder.ps1 +. $PSScriptRoot\Save-DataInfoToFile.ps1 +. $PSScriptRoot\..\Add-ServerNameToFileName.ps1 +. $PSScriptRoot\..\Test-CommandExists.ps1 Function Save-ServerInfoData { - Write-ScriptDebug("Function Enter: Save-ServerInfoData") + Write-Verbose("Function Enter: Save-ServerInfoData") $copyTo = $Script:RootCopyToDirectory + "\General_Server_Info" New-Folder -NewFolder $copyTo -IncludeDisplayCreate $true #Get MSInfo from server msinfo32.exe /nfo (Add-ServerNameToFileName -FilePath ("{0}\msinfo.nfo" -f $copyTo)) - Write-ScriptHost -WriteString ("Waiting for msinfo32.exe process to end before moving on...") -ForegroundColor "Yellow" + Write-Host "Waiting for msinfo32.exe process to end before moving on..." -ForegroundColor "Yellow" while ((Get-Process | Where-Object { $_.ProcessName -eq "msinfo32" }).ProcessName -eq "msinfo32") { Start-Sleep 5; } @@ -18,7 +22,7 @@ Function Save-ServerInfoData { try { $tlsSettings += Get-ChildItem "HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols" -Recurse | Where-Object { $_.Name -like "*TLS*" } -ErrorAction stop } catch { - Write-ScriptDebug("Failed to get child items of 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols'") + Write-Verbose("Failed to get child items of 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols'") Invoke-CatchBlockActions } try { @@ -26,7 +30,7 @@ Function Save-ServerInfoData { $tlsSettings += Get-Item ($currentKey = $regBaseV4 -f "Microsoft") -ErrorAction stop $tlsSettings += Get-Item ($currentKey = $regBaseV4 -f "Wow6432Node\Microsoft") -ErrorAction stop } catch { - Write-ScriptDebug("Failed to get child items of '{0}'" -f $currentKey) + Write-Verbose("Failed to get child items of '{0}'" -f $currentKey) Invoke-CatchBlockActions } try { @@ -34,7 +38,7 @@ Function Save-ServerInfoData { $tlsSettings += Get-Item ($currentKey = $regBaseV2 -f "Microsoft") -ErrorAction stop $tlsSettings += Get-Item ($currentKey = $regBaseV2 -f "Wow6432Node\Microsoft") -ErrorAction stop } catch { - Write-ScriptDebug("Failed to get child items of '{0}'" -f $currentKey) + Write-Verbose("Failed to get child items of '{0}'" -f $currentKey) Invoke-CatchBlockActions } Save-DataInfoToFile -DataIn $tlsSettings -SaveToLocation ("{0}\TLS_RegistrySettings" -f $copyTo) -FormatList $false @@ -77,7 +81,7 @@ Function Save-ServerInfoData { try { $hiveKey = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Exchange\ -Recurse -ErrorAction Stop } catch { - Write-ScriptDebug("Failed to get child item on HKLM:\SOFTWARE\Microsoft\Exchange\") + Write-Verbose("Failed to get child item on HKLM:\SOFTWARE\Microsoft\Exchange\") Invoke-CatchBlockActions } $hiveKey += Get-ChildItem HKLM:\SOFTWARE\Microsoft\ExchangeServer\ -Recurse @@ -91,21 +95,21 @@ Function Save-ServerInfoData { if (Test-CommandExists -command "Get-Volume") { Save-DataInfoToFile -DataIn (Get-Volume) -SaveToLocation ("{0}\Volume" -f $copyTo) } else { - Write-ScriptDebug("Get-Volume isn't a valid command") + Write-Verbose("Get-Volume isn't a valid command") } if (Test-CommandExists -command "Get-Disk") { Save-DataInfoToFile -DataIn (Get-Disk) -SaveToLocation ("{0}\Disk" -f $copyTo) } else { - Write-ScriptDebug("Get-Disk isn't a valid command") + Write-Verbose("Get-Disk isn't a valid command") } if (Test-CommandExists -command "Get-Partition") { Save-DataInfoToFile -DataIn (Get-Partition) -SaveToLocation ("{0}\Partition" -f $copyTo) } else { - Write-ScriptDebug("Get-Partition isn't a valid command") + Write-Verbose("Get-Partition isn't a valid command") } Invoke-ZipFolder -Folder $copyTo - Write-ScriptDebug("Function Exit: Save-ServerInfoData") + Write-Verbose("Function Exit: Save-ServerInfoData") } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-WindowsEventLogs.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-WindowsEventLogs.ps1 index 59a608636f..e435cb374d 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-WindowsEventLogs.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Save-WindowsEventLogs.ps1 @@ -1,9 +1,11 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Copy-BulkItems.ps1 +. $PSScriptRoot\Save-DataInfoToFile.ps1 Function Save-WindowsEventLogs { - Write-ScriptDebug("Function Enter: Save-WindowsEventLogs") + Write-Verbose("Function Enter: Save-WindowsEventLogs") $baseSaveLocation = $Script:RootCopyToDirectory + "\Windows_Event_Logs" $SaveLogs = @{} $rootLogPath = "$env:SystemRoot\System32\Winevt\Logs" @@ -13,7 +15,7 @@ Function Save-WindowsEventLogs { } if ($PassedInfo.AppSysLogs) { - Write-ScriptDebug("Adding Application and System Logs") + Write-Verbose("Adding Application and System Logs") $logs = @() $logs += "$rootLogPath\Application.evtx" $logs += "$rootLogPath\System.evtx" @@ -28,7 +30,7 @@ Function Save-WindowsEventLogs { } if ($PassedInfo.ManagedAvailabilityLogs) { - Write-ScriptDebug("Adding Managed Availability Logs") + Write-Verbose("Adding Managed Availability Logs") $logs = $allLogPaths | Where-Object { $_.Contains("Microsoft-Exchange-ActiveMonitoring") } $SaveLogs.Add("Microsoft-Exchange-ActiveMonitoring", $Logs) @@ -38,7 +40,7 @@ Function Save-WindowsEventLogs { } if ($PassedInfo.HighAvailabilityLogs) { - Write-ScriptDebug("Adding High Availability Logs") + Write-Verbose("Adding High Availability Logs") $logs = $allLogPaths | Where-Object { $_.Contains("Microsoft-Exchange-HighAvailability") } $SaveLogs.Add("Microsoft-Exchange-HighAvailability", $Logs) @@ -51,7 +53,7 @@ Function Save-WindowsEventLogs { } foreach ($directory in $SaveLogs.Keys) { - Write-ScriptDebug("Working on directory: {0}" -f $directory) + Write-Verbose("Working on directory: {0}" -f $directory) $logs = $SaveLogs[$directory] $saveLocation = "$baseSaveLocation\$directory" @@ -62,12 +64,12 @@ Function Save-WindowsEventLogs { if ($directory -eq "Windows-Logs" -and $PassedInfo.AppSysLogsToXml) { try { - Write-ScriptDebug("starting to collect event logs and saving out to xml files.") + Write-Verbose("starting to collect event logs and saving out to xml files.") Save-DataInfoToFile -DataIn (Get-EventLog Application -After ([DateTime]::Now - $PassedInfo.TimeSpan)) -SaveToLocation ("{0}\Application" -f $saveLocation) -SaveTextFile $false Save-DataInfoToFile -DataIn (Get-EventLog System -After ([DateTime]::Now - $PassedInfo.TimeSpan)) -SaveToLocation ("{0}\System" -f $saveLocation) -SaveTextFile $false - Write-ScriptDebug("end of collecting event logs and saving out to xml files.") + Write-Verbose("end of collecting event logs and saving out to xml files.") } catch { - Write-ScriptDebug("Error occurred while trying to export out the Application and System logs to xml") + Write-Verbose("Error occurred while trying to export out the Application and System logs to xml") Invoke-CatchBlockActions } } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-DebugLog.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-DebugLog.ps1 deleted file mode 100644 index 7972a4f610..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-DebugLog.ps1 +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#Calls the $Script:Logger object to write the data to file only. -Function Write-DebugLog($message) { - if ($null -ne $message -and - ![string]::IsNullOrEmpty($message) -and - $null -ne $Script:Logger) { - $Script:Logger.WriteToFileOnly($message) - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptDebug.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptDebug.ps1 deleted file mode 100644 index 203645dfb2..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptDebug.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Write-ScriptDebug { - param( - [Parameter(Mandatory = $true)]$WriteString - ) - Write-DebugLog $WriteString - - if ($PassedInfo.ScriptDebug -or $Script:ScriptDebug) { - Write-Host("[{0} - Script Debug] : {1}" -f $env:COMPUTERNAME, $WriteString) -ForegroundColor Cyan - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptHost.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptHost.ps1 deleted file mode 100644 index d13a9560dd..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-ScriptHost.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Write-ScriptHost { - param( - [Parameter(Mandatory = $true)][string]$WriteString, - [Parameter(Mandatory = $false)][bool]$ShowServer = $true, - [Parameter(Mandatory = $false)][string]$ForegroundColor = "Gray", - [Parameter(Mandatory = $false)][bool]$NoNewLine = $false - ) - Write-DebugLog $WriteString - - if ($ShowServer) { - - if ($WriteString.StartsWith("[")) { - Write-Host ($WriteString.Insert(1, "$env:COMPUTERNAME - ")) -ForegroundColor $ForegroundColor -NoNewline:$NoNewLine - } else { - Write-Host("[{0}] : {1}" -f $env:COMPUTERNAME, $WriteString) -ForegroundColor $ForegroundColor -NoNewline:$NoNewLine - } - } else { - Write-Host("{0}" -f $WriteString) -ForegroundColor $ForegroundColor -NoNewline:$NoNewLine - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-Verbose.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-Verbose.ps1 new file mode 100644 index 0000000000..479b417e80 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/Write-Verbose.ps1 @@ -0,0 +1,42 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Function Write-Verbose { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification = 'In order to log Write-Verbose from Shared functions')] + [CmdletBinding()] + param( + [Parameter(Position = 1, ValueFromPipeline)] + [string]$Message + ) + + process { + + if ($null -ne $Script:WriteVerboseManipulateMessageAction) { + $Message = & $Script:WriteVerboseManipulateMessageAction $Message + } + + Microsoft.PowerShell.Utility\Write-Verbose $Message + + if ($null -ne $Script:WriteVerboseDebugAction) { + & $Script:WriteVerboseDebugAction $Message + } + + # $PSSenderInfo is set when in a remote context + if ($PSSenderInfo -and + $null -ne $Script:WriteRemoteVerboseDebugAction) { + & $Script:WriteRemoteVerboseDebugAction $Message + } + } +} + +Function SetWriteVerboseAction ($DebugAction) { + $Script:WriteVerboseDebugAction = $DebugAction +} + +Function SetWriteRemoteVerboseAction ($DebugAction) { + $Script:WriteRemoteVerboseDebugAction = $DebugAction +} + +Function SetWriteVerboseManipulateMessageAction ($DebugAction) { + $Script:WriteVerboseManipulateMessageAction = $DebugAction +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/WriteFunctions.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/WriteFunctions.ps1 new file mode 100644 index 0000000000..3bb77a44f8 --- /dev/null +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/IO/WriteFunctions.ps1 @@ -0,0 +1,38 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# Small set of functions that are used to help override the Write-Host and Write-Verbose functions +Function Get-ManipulateWriteHostValue { + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Position = 1, ValueFromPipeline)] + [string]$Message + ) + + process { + return "[$env:COMPUTERNAME] : $Message" + } +} + +Function Get-ManipulateWriteVerboseValue { + [CmdletBinding()] + [OutputType([string])] + param( + [Parameter(Position = 1, ValueFromPipeline)] + [string]$Message + ) + + process { + return "[$env:COMPUTERNAME - Script Debug] : $Message" + } +} + +#Calls the $Script:Logger object to write the data to file only. +Function Write-DebugLog($message) { + if ($null -ne $message -and + ![string]::IsNullOrEmpty($message) -and + $null -ne $Script:Logger) { + $Script:Logger = $Script:Logger | Write-LoggerInstance $message + } +} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-RemoteMain.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-RemoteMain.ps1 index 44530fe5b6..021556603f 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-RemoteMain.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-RemoteMain.ps1 @@ -1,11 +1,23 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-ExchangeInstallDirectory.ps1 +. $PSScriptRoot\Get-FreeSpace.ps1 +. $PSScriptRoot\Get-IISLogDirectory.ps1 +. $PSScriptRoot\IO\Copy-BulkItems.ps1 +. $PSScriptRoot\IO\Copy-FullLogFullPathRecurse.ps1 +. $PSScriptRoot\IO\Copy-LogsBasedOnTime.ps1 +. $PSScriptRoot\IO\Save-DataInfoToFile.ps1 +. $PSScriptRoot\IO\Save-FailoverClusterInformation.ps1 +. $PSScriptRoot\IO\Save-LogmanExmonData.ps1 +. $PSScriptRoot\IO\Save-LogmanExperfwizData.ps1 +. $PSScriptRoot\IO\Save-ServerInfoData.ps1 +. $PSScriptRoot\IO\Save-WindowsEventLogs.ps1 Function Invoke-RemoteMain { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = 'Required to be used in the current format')] [CmdletBinding()] param() - Write-ScriptDebug("Function Enter: Remote-Main") + Write-Verbose("Function Enter: Remote-Main") foreach ($server in $PassedInfo.ServerObjects) { @@ -17,7 +29,7 @@ Function Invoke-RemoteMain { if ($null -eq $Script:localServerObject -or $Script:localServerObject.ServerName -ne $env:COMPUTERNAME) { - Write-ScriptHost -WriteString ("Something went wrong trying to find the correct Server Object for this server. Stopping this instance of execution.") + Write-Host "Something went wrong trying to find the correct Server Object for this server. Stopping this instance of execution." exit } @@ -38,7 +50,7 @@ Function Invoke-RemoteMain { $copyInfo = "-LogPath '{0}' -CopyToThisLocation '{1}'" if ($Script:localServerObject.Version -ge 15) { - Write-ScriptDebug("Server Version greater than 15") + Write-Verbose("Server Version greater than 15") if ($PassedInfo.EWSLogs) { @@ -254,10 +266,10 @@ Function Invoke-RemoteMain { if (!$logmanRootPath.ToString().Contains($copyFrom)) { $copyFrom = $logmanRootPath.ToString().Replace("Root Path:", "").Trim() - Write-ScriptDebug "Changing the location to get the daily performance logs to '$copyFrom'" + Write-Verbose "Changing the location to get the daily performance logs to '$copyFrom'" } } catch { - Write-ScriptDebug "Couldn't get logman info to verify Daily Performance Logs location" + Write-Verbose "Couldn't get logman info to verify Daily Performance Logs location" Invoke-CatchBlockActions } @@ -426,7 +438,7 @@ Function Invoke-RemoteMain { if ($PassedInfo.FrontEndConnectivityLogs -and (-not ($Script:localServerObject.Version -eq 15 -and $Script:localServerObject.MailboxOnly))) { - Write-ScriptDebug("Collecting FrontEndConnectivityLogs") + Write-Verbose("Collecting FrontEndConnectivityLogs") $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.FELoggingInfo.ConnectivityLogPath), ($Script:RootCopyToDirectory + "\FE_Connectivity_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info } @@ -434,7 +446,7 @@ Function Invoke-RemoteMain { if ($PassedInfo.FrontEndProtocolLogs -and (-not ($Script:localServerObject.Version -eq 15 -and $Script:localServerObject.MailboxOnly))) { - Write-ScriptDebug("Collecting FrontEndProtocolLogs") + Write-Verbose("Collecting FrontEndProtocolLogs") $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.FELoggingInfo.ReceiveProtocolLogPath), ($Script:RootCopyToDirectory + "\FE_Receive_Protocol_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.FELoggingInfo.SendProtocolLogPath), ($Script:RootCopyToDirectory + "\FE_Send_Protocol_Logs")) @@ -444,7 +456,7 @@ Function Invoke-RemoteMain { if ($PassedInfo.MailboxConnectivityLogs -and (-not ($Script:localServerObject.Version -eq 15 -and $Script:localServerObject.CASOnly))) { - Write-ScriptDebug("Collecting MailboxConnectivityLogs") + Write-Verbose("Collecting MailboxConnectivityLogs") $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.MBXLoggingInfo.ConnectivityLogPath + "\Delivery"), ($Script:RootCopyToDirectory + "\MBX_Delivery_Connectivity_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.MBXLoggingInfo.ConnectivityLogPath + "\Submission"), ($Script:RootCopyToDirectory + "\MBX_Submission_Connectivity_Logs")) @@ -454,7 +466,7 @@ Function Invoke-RemoteMain { if ($PassedInfo.MailboxProtocolLogs -and (-not ($Script:localServerObject.Version -eq 15 -and $Script:localServerObject.CASOnly))) { - Write-ScriptDebug("Collecting MailboxProtocolLogs") + Write-Verbose("Collecting MailboxProtocolLogs") $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.MBXLoggingInfo.ReceiveProtocolLogPath), ($Script:RootCopyToDirectory + "\MBX_Receive_Protocol_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.MBXLoggingInfo.SendProtocolLogPath), ($Script:RootCopyToDirectory + "\MBX_Send_Protocol_Logs")) @@ -464,7 +476,7 @@ Function Invoke-RemoteMain { if ($PassedInfo.MailboxDeliveryThrottlingLogs -and (!($Script:localServerObject.Version -eq 15 -and $Script:localServerObject.CASOnly))) { - Write-ScriptDebug("Collecting Mailbox Delivery Throttling Logs") + Write-Verbose("Collecting Mailbox Delivery Throttling Logs") $info = ($copyInfo -f ($Script:localServerObject.TransportInfo.MBXLoggingInfo.MailboxDeliveryThrottlingLogPath), ($Script:RootCopyToDirectory + "\MBX_Delivery_Throttling_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info } @@ -472,13 +484,13 @@ Function Invoke-RemoteMain { } if ($PassedInfo.ImapLogs) { - Write-ScriptDebug("Collecting IMAP Logs") + Write-Verbose("Collecting IMAP Logs") $info = ($copyInfo -f ($Script:localServerObject.ImapLogsLocation), ($Script:RootCopyToDirectory + "\Imap_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info } if ($PassedInfo.PopLogs) { - Write-ScriptDebug("Collecting POP Logs") + Write-Verbose("Collecting POP Logs") $info = ($copyInfo -f ($Script:localServerObject.PopLogsLocation), ($Script:RootCopyToDirectory + "\Pop_Logs")) $cmdsToRun += "Copy-LogsBasedOnTime {0}" -f $info } @@ -512,12 +524,12 @@ Function Invoke-RemoteMain { #Execute the cmds foreach ($cmd in $cmdsToRun) { - Write-ScriptDebug("cmd: {0}" -f $cmd) + Write-Verbose("cmd: {0}" -f $cmd) try { Invoke-Expression $cmd -ErrorAction Stop } catch { - Write-ScriptDebug("Failed to finish running command: $cmd") + Write-Verbose("Failed to finish running command: $cmd") Invoke-CatchBlockActions } } @@ -526,7 +538,7 @@ Function Invoke-RemoteMain { Save-DataInfoToFile -DataIn $Error -SaveToLocation ("$Script:RootCopyToDirectory\AllErrors") Save-DataInfoToFile -DataIn $Script:ErrorsHandled -SaveToLocation ("$Script:RootCopyToDirectory\HandledErrors") } else { - Write-ScriptDebug ("No errors occurred within the script") + Write-Verbose ("No errors occurred within the script") } } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-ZipFolder.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-ZipFolder.ps1 index b236fb3b54..13ca72bc25 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-ZipFolder.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Invoke-ZipFolder.ps1 @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-ItemsSize.ps1 +. $PSScriptRoot\IO\Compress-Folder.ps1 Function Invoke-ZipFolder { param( [string]$Folder, @@ -9,15 +11,15 @@ Function Invoke-ZipFolder { ) if ($ZipItAll) { - Write-ScriptDebug("Disabling Logger before zipping up the directory") - $Script:Logger.DisableLogger() + Write-Verbose("Disabling Logger before zipping up the directory") + $Script:Logger.LoggerDisabled = $true Compress-Folder -Folder $Folder -IncludeMonthDay $true } else { $compressedLocation = Compress-Folder -Folder $Folder -ReturnCompressedLocation $AddCompressedSize if ($AddCompressedSize -and ($compressedLocation -ne [string]::Empty)) { $Script:TotalBytesSizeCompressed += ($size = Get-ItemsSize -FilePaths $compressedLocation) $Script:FreeSpaceMinusCopiedAndCompressedGB -= ($size / 1GB) - Write-ScriptDebug("Current Sizes after compression: [double]TotalBytesSizeCompressed: {0} | [double]FreeSpaceMinusCopiedAndCompressedGB: {1}" -f $Script:TotalBytesSizeCompressed, + Write-Verbose("Current Sizes after compression: [double]TotalBytesSizeCompressed: {0} | [double]FreeSpaceMinusCopiedAndCompressedGB: {1}" -f $Script:TotalBytesSizeCompressed, $Script:FreeSpaceMinusCopiedAndCompressedGB) } } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanData.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanData.ps1 index d59fbae083..1cd6c979f8 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanData.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanData.ps1 @@ -1,6 +1,10 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-LogmanObject.ps1 +. $PSScriptRoot\Start-Logman.ps1 +. $PSScriptRoot\Stop-Logman.ps1 +. $PSScriptRoot\..\IO\Copy-LogmanData.ps1 Function Get-LogmanData { param( [Parameter(Mandatory = $true)][string]$LogmanName, @@ -11,32 +15,32 @@ Function Get-LogmanData { if ($null -ne $objLogman) { switch ($objLogman.Status) { "Running" { - Write-ScriptHost -WriteString ("Looks like logman {0} is running...." -f $LogmanName) - Write-ScriptHost -WriteString ("Going to stop {0} to prevent corruption...." -f $LogmanName) + Write-Host "Looks like logman $LogmanName is running...." + Write-Host "Going to stop $LogmanName to prevent corruption...." Stop-Logman -LogmanName $LogmanName -ServerName $ServerName Copy-LogmanData -ObjLogman $objLogman - Write-ScriptHost -WriteString ("Starting Logman {0} again for you...." -f $LogmanName) + Write-Host "Starting Logman $LogmanName again for you...." Start-Logman -LogmanName $LogmanName -ServerName $ServerName - Write-ScriptHost -WriteString ("Done starting Logman {0} for you" -f $LogmanName) + Write-Host "Done starting Logman $LogmanName for you" break } "Stopped" { - Write-ScriptHost -WriteString ("Doesn't look like Logman {0} is running, so not going to stop it..." -f $LogmanName) + Write-Host "Doesn't look like Logman $LogmanName is running, so not going to stop it..." Copy-LogmanData -ObjLogman $objLogman break } Default { - Write-ScriptHost -WriteString ("Don't know what the status of Logman '{0}' is in" -f $LogmanName) - Write-ScriptHost -WriteString ("This is the status: {0}" -f $objLogman.Status) - Write-ScriptHost -WriteString ("Going to try stop it just in case...") + Write-Host "Don't know what the status of Logman '$LogmanName' is in" + Write-Host "This is the status: $($objLogman.Status)" + Write-Host "Going to try stop it just in case..." Stop-Logman -LogmanName $LogmanName -ServerName $ServerName Copy-LogmanData -ObjLogman $objLogman - Write-ScriptHost -WriteString ("Not going to start it back up again....") - Write-ScriptHost -WriteString ("Please start this logman '{0}' if you need to...." -f $LogmanName) -ForegroundColor "Yellow" + Write-Host "Not going to start it back up again...." + Write-Host "Please start this logman '$LogmanName' if you need to...." -ForegroundColor "Yellow" break } } } else { - Write-ScriptHost -WriteString ("Can't find {0} on {1} ..... Moving on." -f $LogmanName, $ServerName) + Write-Host "Can't find $LogmanName on $ServerName ..... Moving on." } } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanObject.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanObject.ps1 index a21c1e9f46..ec7ebc56d4 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanObject.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Get-LogmanObject.ps1 @@ -1,6 +1,10 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-LogmanExt.ps1 +. $PSScriptRoot\Get-LogmanRootPath.ps1 +. $PSScriptRoot\Get-LogmanStartDate.ps1 +. $PSScriptRoot\Get-LogmanStatus.ps1 Function Get-LogmanObject { param( [Parameter(Mandatory = $true)][string]$LogmanName, diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Start-Logman.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Start-Logman.ps1 index 3b9db00c12..f66fc87491 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Start-Logman.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Start-Logman.ps1 @@ -7,6 +7,6 @@ Function Start-Logman { [Parameter(Mandatory = $true)][string]$LogmanName, [Parameter(Mandatory = $true)][string]$ServerName ) - Write-ScriptHost -WriteString ("Starting Data Collection {0} on server {1}" -f $LogmanName, $ServerName) + Write-Host "Starting Data Collection $LogmanName on server $ServerName" logman start -s $ServerName $LogmanName } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Stop-Logman.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Stop-Logman.ps1 index 3793e08fd7..8f9657f14d 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Stop-Logman.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Logman/Stop-Logman.ps1 @@ -7,6 +7,6 @@ Function Stop-Logman { [Parameter(Mandatory = $true)][string]$LogmanName, [Parameter(Mandatory = $true)][string]$ServerName ) - Write-ScriptHost -WriteString ("Stopping Data Collection {0} on server {1}" -f $LogmanName, $ServerName) + Write-Host "Stopping Data Collection $LogmanName on server $ServerName" logman stop -s $ServerName $LogmanName } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Test-FreeSpace.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Test-FreeSpace.ps1 index 177e614590..6a4090431d 100644 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Test-FreeSpace.ps1 +++ b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/Test-FreeSpace.ps1 @@ -1,15 +1,17 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\Get-FreeSpace.ps1 +. $PSScriptRoot\Get-ItemsSize.ps1 Function Test-FreeSpace { param( [Parameter(Mandatory = $false)][array]$FilePaths ) - Write-ScriptDebug("Calling: Test-FreeSpace") + Write-Verbose("Calling: Test-FreeSpace") if ($null -eq $FilePaths -or $FilePaths.Count -eq 0) { - Write-ScriptDebug("Null FilePaths provided returning true.") + Write-Verbose("Null FilePaths provided returning true.") return $true } @@ -17,17 +19,17 @@ Function Test-FreeSpace { $currentSizeCopy = Get-ItemsSize -FilePaths $FilePaths #It is better to be safe than sorry, checking against probably a value way higher than needed. if (($Script:FreeSpaceMinusCopiedAndCompressedGB - ($currentSizeCopy / 1GB)) -lt $Script:AdditionalFreeSpaceCushionGB) { - Write-ScriptDebug("Estimated free space is getting low, going to recalculate.") - Write-ScriptDebug("Current values: [double]FreeSpaceMinusCopiedAndCompressedGB: {0} | [double]currentSizeCopy: {1} | [double]AdditionalFreeSpaceCushionGB: {2} | [double]CurrentFreeSpaceGB: {3}" -f $Script:FreeSpaceMinusCopiedAndCompressedGB, + Write-Verbose("Estimated free space is getting low, going to recalculate.") + Write-Verbose("Current values: [double]FreeSpaceMinusCopiedAndCompressedGB: {0} | [double]currentSizeCopy: {1} | [double]AdditionalFreeSpaceCushionGB: {2} | [double]CurrentFreeSpaceGB: {3}" -f $Script:FreeSpaceMinusCopiedAndCompressedGB, ($currentSizeCopy / 1GB), $Script:AdditionalFreeSpaceCushionGB, $Script:CurrentFreeSpaceGB) $freeSpace = Get-FreeSpace -FilePath ("{0}\" -f $Script:RootCopyToDirectory) - Write-ScriptDebug("True current free space: {0}" -f $freeSpace) + Write-Verbose("True current free space: {0}" -f $freeSpace) if ($freeSpace -lt ($Script:CurrentFreeSpaceGB - .5)) { #If we off by .5GB, we need to know about this and look at the data to determine if we might have some logical errors. It is possible that the disk is that active, but that wouldn't be good either for this script. - Write-ScriptDebug("CRIT: Disk Space logic is off. CurrentFreeSpaceGB: {0} | ActualFreeSpace: {1}" -f $Script:CurrentFreeSpaceGB, $freeSpace) + Write-Verbose("CRIT: Disk Space logic is off. CurrentFreeSpaceGB: {0} | ActualFreeSpace: {1}" -f $Script:CurrentFreeSpaceGB, $freeSpace) } $Script:CurrentFreeSpaceGB = $freeSpace @@ -35,8 +37,8 @@ Function Test-FreeSpace { $passed = $freeSpace -gt ($addSize = $Script:AdditionalFreeSpaceCushionGB + ($currentSizeCopy / 1GB)) if (!($passed)) { - Write-ScriptHost("Free space on the drive has appear to be used up past recommended thresholds. Going to stop this execution of the script. If you feel this is an Error, please notify ExToolsFeedback@microsoft.com") -ShowServer $true -ForegroundColor "Red" - Write-ScriptHost("FilePath: {0} | FreeSpace: {1} | Looking for: {2}" -f $Script:RootCopyToDirectory, $freeSpace, ($freeSpace + $addSize)) -ShowServer $true -ForegroundColor "Red" + Write-Host "Free space on the drive has appear to be used up past recommended thresholds. Going to stop this execution of the script. If you feel this is an Error, please notify ExToolsFeedback@microsoft.com" -ForegroundColor "Red" + Write-Host "FilePath: $($Script:RootCopyToDirectory) | FreeSpace: $freeSpace | Looking for: $(($freeSpace + $addSize))" -ForegroundColor "Red" return $passed } } @@ -44,7 +46,7 @@ Function Test-FreeSpace { $Script:TotalBytesSizeCopied += $currentSizeCopy $Script:FreeSpaceMinusCopiedAndCompressedGB = $Script:FreeSpaceMinusCopiedAndCompressedGB - ($currentSizeCopy / 1GB) - Write-ScriptDebug("Current values [double]FreeSpaceMinusCopiedAndCompressedGB: {0} | [double]TotalBytesSizeCopied: {1}" -f $Script:FreeSpaceMinusCopiedAndCompressedGB, $Script:TotalBytesSizeCopied) - Write-ScriptDebug("Returning: {0}" -f $passed) + Write-Verbose("Current values [double]FreeSpaceMinusCopiedAndCompressedGB: {0} | [double]TotalBytesSizeCopied: {1}" -f $Script:FreeSpaceMinusCopiedAndCompressedGB, $Script:TotalBytesSizeCopied) + Write-Verbose("Returning: {0}" -f $passed) return $passed } diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Compress-Folder.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Compress-Folder.ps1 deleted file mode 100644 index 5b4a70768e..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Compress-Folder.ps1 +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Compress-Folder/Compress-Folder.ps1 -#v21.01.22.2234 -Function Compress-Folder { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'Because it returns different types that needs to be addressed')] - [CmdletBinding()] - param( - [Parameter(Mandatory = $false)][string]$Folder, - [Parameter(Mandatory = $false)][bool]$IncludeMonthDay = $false, - [Parameter(Mandatory = $false)][bool]$IncludeDisplayZipping = $true, - [Parameter(Mandatory = $false)][bool]$ReturnCompressedLocation = $false, - [Parameter(Mandatory = $false, Position = 1)][object]$PassedObjectParameter - ) - #Function Version #v21.01.22.2234 - - Function Get-DirectorySize { - param( - [Parameter(Mandatory = $true)][string]$Directory, - [Parameter(Mandatory = $false)][bool]$IsCompressed = $false - ) - Write-InvokeCommandReturnVerboseWriter("Calling: Get-DirectorySize") - Write-InvokeCommandReturnVerboseWriter("Passed: [string]Directory: {0} | [bool]IsCompressed: {1}" -f $Directory, $IsCompressed) - $itemSize = 0 - if ($IsCompressed) { - $itemSize = (Get-Item $Directory).Length - } else { - $childItems = Get-ChildItem $Directory -Recurse | Where-Object { -not($_.Mode.StartsWith("d-")) } - foreach ($item in $childItems) { - $itemSize += $item.Length - } - } - return $itemSize - } - Function Enable-IOCompression { - $successful = $true - Write-InvokeCommandReturnVerboseWriter("Calling: Enable-IOCompression") - try { - Add-Type -AssemblyName System.IO.Compression.Filesystem -ErrorAction Stop - } catch { - Write-InvokeCommandReturnHostWriter("Failed to load .NET Compression assembly. Unable to compress up the data.") - $successful = $false - } - Write-InvokeCommandReturnVerboseWriter("Returned: [bool]{0}" -f $successful) - return $successful - } - Function Confirm-IOCompression { - Write-InvokeCommandReturnVerboseWriter("Calling: Confirm-IOCompression") - $assemblies = [Appdomain]::CurrentDomain.GetAssemblies() - $successful = $false - foreach ($assembly in $assemblies) { - if ($assembly.Location -like "*System.IO.Compression.Filesystem*") { - $successful = $true - break - } - } - Write-InvokeCommandReturnVerboseWriter("Returned: [bool]{0}" -f $successful) - return $successful - } - - Function Compress-Now { - Write-InvokeCommandReturnVerboseWriter("Calling: Compress-Now ") - $zipFolder = Get-ZipFolderName -Folder $Folder -IncludeMonthDay $IncludeMonthDay - if ($IncludeDisplayZipping) { - Write-InvokeCommandReturnHostWriter("Compressing Folder {0}" -f $Folder) - } - $sizeBytesBefore = Get-DirectorySize -Directory $Folder - $timer = [System.Diagnostics.Stopwatch]::StartNew() - [System.IO.Compression.ZipFile]::CreateFromDirectory($Folder, $zipFolder) - $timer.Stop() - $sizeBytesAfter = Get-DirectorySize -Directory $zipFolder -IsCompressed $true - Write-InvokeCommandReturnVerboseWriter("Compressing directory size of {0} MB down to the size of {1} MB took {2} seconds." -f ($sizeBytesBefore / 1MB), ($sizeBytesAfter / 1MB), $timer.Elapsed.TotalSeconds) - if ((Test-Path -Path $zipFolder)) { - Write-InvokeCommandReturnVerboseWriter("Compress successful, removing folder.") - Remove-Item $Folder -Force -Recurse - } - if ($ReturnCompressedLocation) { - Set-Variable -Name compressedLocation -Value $zipFolder -Scope 1 - } - } - - Function Get-ZipFolderName { - param( - [Parameter(Mandatory = $true)][string]$Folder, - [Parameter(Mandatory = $false)][bool]$IncludeMonthDay = $false - ) - Write-InvokeCommandReturnVerboseWriter("Calling: Get-ZipFolderName") - Write-InvokeCommandReturnVerboseWriter("Passed - [string]Folder:{0} | [bool]IncludeMonthDay:{1}" -f $Folder, $IncludeMonthDay) - if ($IncludeMonthDay) { - $zipFolderNoEXT = "{0}-{1}" -f $Folder, (Get-Date -Format Md) - } else { - $zipFolderNoEXT = $Folder - } - Write-InvokeCommandReturnVerboseWriter("[string]zipFolderNoEXT: {0}" -f $zipFolderNoEXT) - $zipFolder = "{0}.zip" -f $zipFolderNoEXT - if (Test-Path $zipFolder) { - [int]$i = 1 - do { - $zipFolder = "{0}-{1}.zip" -f $zipFolderNoEXT, $i - $i++ - }while (Test-Path $zipFolder) - } - Write-InvokeCommandReturnVerboseWriter("Returned: [string]zipFolder {0}" -f $zipFolder) - return $zipFolder - } - - $Script:stringArray = @() - if ($null -ne $PassedObjectParameter) { - if ($null -ne $PassedObjectParameter.Folder) { - $Folder = $PassedObjectParameter.Folder - if ($null -ne $PassedObjectParameter.IncludeDisplayZipping) { - $IncludeDisplayZipping = $PassedObjectParameter.IncludeDisplayZipping - } - if ($null -ne $PassedObjectParameter.ReturnCompressedLocation) { - $ReturnCompressedLocation = $PassedObjectParameter.ReturnCompressedLocation - } - if ($null -ne $PassedObjectParameter.IncludeMonthDay) { - $IncludeMonthDay = $PassedObjectParameter.IncludeMonthDay - } - } else { - $Folder = $PassedObjectParameter - } - $InvokeCommandReturnWriteArray = $true - } - if ($Folder.EndsWith("\")) { - $Folder = $Folder.TrimEnd("\") - } - Write-InvokeCommandReturnVerboseWriter("Calling: Compress-Folder") - Write-InvokeCommandReturnVerboseWriter("Passed - [string]Folder: {0} | [bool]IncludeDisplayZipping: {1} | [bool]ReturnCompressedLocation: {2}" -f $Folder, - $IncludeDisplayZipping, - $ReturnCompressedLocation) - - $compressedLocation = [string]::Empty - if (Test-Path $Folder) { - if (Confirm-IOCompression) { - Compress-Now - } else { - if (Enable-IOCompression) { - Compress-Now - } else { - Write-InvokeCommandReturnHostWriter("Unable to compress folder {0}" -f $Folder) - Write-InvokeCommandReturnVerboseWriter("Unable to enable IO compression on this system") - } - } - } else { - Write-InvokeCommandReturnHostWriter("Failed to find the folder {0}" -f $Folder) - } - if ($InvokeCommandReturnWriteArray) { - if ($ReturnCompressedLocation) { - Write-InvokeCommandReturnVerboseWriter("Returning: {0}" -f $compressedLocation) - $hashTable = @{"ReturnObject" = $compressedLocation } - $Script:stringArray += $hashTable - return $Script:stringArray - } else { - return $Script:stringArray - } - } - if ($ReturnCompressedLocation) { - Write-InvokeCommandReturnVerboseWriter("Returning: {0}" -f $compressedLocation) - return $compressedLocation - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ExchangeInstallDirectory.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ExchangeInstallDirectory.ps1 deleted file mode 100644 index 69c40a0b25..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-ExchangeInstallDirectory.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/ExchangeInformation/Get-ExchangeInstallDirectory/Get-ExchangeInstallDirectory.ps1 -#v21.01.22.2234 -Function Get-ExchangeInstallDirectory { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'Different types returned')] - [CmdletBinding()] - param( - [Parameter(Mandatory = $false)][bool]$InvokeCommandReturnWriteArray - ) - #Function Version #v21.01.22.2234 - - $stringArray = @() - Write-InvokeCommandReturnVerboseWriter("Calling: Get-ExchangeInstallDirectory") - Write-InvokeCommandReturnVerboseWriter("Passed: [bool]InvokeCommandReturnWriteArray: {0}" -f $InvokeCommandReturnWriteArray) - - $installDirectory = [string]::Empty - if (Test-Path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup') { - Write-InvokeCommandReturnVerboseWriter("Detected v14") - $installDirectory = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath - } elseif (Test-Path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\Setup') { - Write-InvokeCommandReturnVerboseWriter("Detected v15") - $installDirectory = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v15\Setup).MsiInstallPath - } else { - Write-InvokeCommandReturnHostWriter -WriteString ("Something went wrong trying to find Exchange Install path on this server: {0}" -f $env:COMPUTERNAME) - } - Write-InvokeCommandReturnVerboseWriter("Returning: {0}" -f $installDirectory) - if ($InvokeCommandReturnWriteArray) { - $hashTable = @{"ReturnObject" = $installDirectory } - $stringArray += $hashTable - return $stringArray - } - return $installDirectory -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-FreeSpace.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-FreeSpace.ps1 deleted file mode 100644 index 98a4d5961f..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Get-FreeSpace.ps1 +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/ComputerInformation/Get-FreeSpace/Get-FreeSpace.ps1 -#v21.01.22.2234 -Function Get-FreeSpace { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWMICmdlet', '', Justification = 'Different types returned')] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Different types returned')] - [CmdletBinding()] - param( - [Parameter(Mandatory = $false)][ValidateScript( { $_.ToString().EndsWith("\") })][string]$FilePath, - [Parameter(Mandatory = $false, Position = 1)][object]$PassedObjectParameter - ) - #Function Version #v21.01.22.2234 - - if ($null -ne $PassedObjectParameter) { - if ($null -ne $PassedObjectParameter.FilePath) { - $FilePath = $PassedObjectParameter.FilePath - } else { - $FilePath = $PassedObjectParameter - } - $InvokeCommandReturnWriteArray = $true - } - $stringArray = @() - Write-InvokeCommandReturnVerboseWriter("Calling: Get-FreeSpace") - Write-InvokeCommandReturnVerboseWriter("Passed: [string]FilePath: {0}" -f $FilePath) - - Function Update-TestPath { - param( - [Parameter(Mandatory = $true)][string]$FilePath - ) - $updateFilePath = $FilePath.Substring(0, $FilePath.LastIndexOf("\", $FilePath.Length - 2) + 1) - return $updateFilePath - } - - Function Get-MountPointItemTarget { - param( - [Parameter(Mandatory = $true)][string]$FilePath - ) - $itemTarget = [string]::Empty - if (Test-Path $testPath) { - $item = Get-Item $FilePath - if ($item.Target -like "Volume{*}\") { - Write-InvokeCommandReturnVerboseWriter("File Path appears to be a mount point target: {0}" -f $item.Target) - $itemTarget = $item.Target - } else { - Write-InvokeCommandReturnVerboseWriter("Path didn't appear to be a mount point target") - } - } else { - Write-InvokeCommandReturnVerboseWriter("Path isn't a true path yet.") - } - return $itemTarget - } - - Function Invoke-ReturnValue { - param( - [Parameter(Mandatory = $true)][int]$FreeSpaceSize - ) - if ($InvokeCommandReturnWriteArray) { - $hashTable = @{"ReturnObject" = $freeSpaceSize } - Set-Variable stringArray -Value ($stringArray += $hashTable) -Scope 1 - return $stringArray - } - return $FreeSpaceSize - } - - $drivesList = Get-WmiObject Win32_Volume -Filter "drivetype = 3" - $testPath = $FilePath - $freeSpaceSize = -1 - while ($true) { - if ($testPath -eq [string]::Empty) { - Write-InvokeCommandReturnHostWriter("Unable to fine a drive that matches the file path: {0}" -f $FilePath) - return (Invoke-ReturnValue -FreeSpaceSize $freeSpaceSize) - } - Write-InvokeCommandReturnVerboseWriter("Trying to find path that matches path: {0}" -f $testPath) - foreach ($drive in $drivesList) { - if ($drive.Name -eq $testPath) { - Write-InvokeCommandReturnVerboseWriter("Found a match") - $freeSpaceSize = $drive.FreeSpace / 1GB - Write-InvokeCommandReturnVerboseWriter("Have {0}GB of Free Space" -f $freeSpaceSize) - return (Invoke-ReturnValue -FreeSpaceSize $freeSpaceSize) - } - Write-InvokeCommandReturnVerboseWriter("Drive name: '{0}' didn't match" -f $drive.Name) - } - - $itemTarget = Get-MountPointItemTarget -FilePath $testPath - if ($itemTarget -ne [string]::Empty) { - foreach ($drive in $drivesList) { - if ($drive.DeviceID.Contains($itemTarget)) { - $freeSpaceSize = $drive.FreeSpace / 1GB - Write-InvokeCommandReturnVerboseWriter("Have {0}GB of Free Space" -f $freeSpaceSize) - return (Invoke-ReturnValue -FreeSpaceSize $freeSpaceSize) - } - Write-InvokeCommandReturnVerboseWriter("DeviceID didn't appear to match: {0}" -f $drive.DeviceID) - } - if ($freeSpaceSize -eq -1) { - Write-InvokeCommandReturnHostWriter("Unable to fine a drive that matches the file path: {0}" -f $FilePath) - Write-InvokeCommandReturnHostWriter("This shouldn't have happened.") - return (Invoke-ReturnValue -FreeSpaceSize $freeSpaceSize) - } - } - $testPath = Update-TestPath -FilePath $testPath - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/New-Folder.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/New-Folder.ps1 deleted file mode 100644 index 2e51a4a4fe..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/New-Folder.ps1 +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/New-Folder/New-Folder.ps1 -#v21.01.22.2234 -Function New-Folder { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'I prefer New here')] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'Multiple output types')] - [CmdletBinding()] - param( - [Alias("NewFolder")] - [Parameter(Mandatory = $false)][array]$NewFolders, - [Parameter(Mandatory = $false)][bool]$IncludeDisplayCreate, - [Parameter(Mandatory = $false, Position = 1)][object]$PassedParametersObject - ) - #Function Version #v21.01.22.2234 - - Function New-Directory { - param( - [Parameter(Mandatory = $false)][string]$NewFolder - ) - if (-not (Test-Path -Path $NewFolder)) { - if ($IncludeDisplayCreate -or $InvokeCommandReturnWriteArray) { - Write-InvokeCommandReturnHostWriter("Creating Directory: {0}" -f $NewFolder) - } - [System.IO.Directory]::CreateDirectory($NewFolder) | Out-Null - } else { - if ($IncludeDisplayCreate -or $InvokeCommandReturnWriteArray) { - Write-InvokeCommandReturnHostWriter("Directory {0} is already created!" -f $NewFolder) - } - } - } - - $Script:stringArray = @() - if ($null -ne $PassedParametersObject) { - if ($null -ne $PassedParametersObject.NewFolders) { - $NewFolders = $PassedParametersObject.NewFolders - } else { - $NewFolders = $PassedParametersObject - } - $InvokeCommandReturnWriteArray = $true - } - if ($NewFolders.Count -gt 1) { - $verboseDisplayNewFolders = "Multiple ('{0}') Folders Passed" -f $NewFolders.Count - } else { - $verboseDisplayNewFolders = $NewFolders[0] - } - Write-InvokeCommandReturnVerboseWriter("Calling: New-Folder") - Write-InvokeCommandReturnVerboseWriter("Passed: [string]NewFolders: {0} | [bool]IncludeDisplayCreate: {1}" -f $verboseDisplayNewFolders, - $IncludeDisplayCreate) - - foreach ($newFolder in $NewFolders) { - New-Directory -NewFolder $newFolder - } - - if ($InvokeCommandReturnWriteArray) { - return $Script:stringArray - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnHostWriter.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnHostWriter.ps1 deleted file mode 100644 index 34bcc1dadc..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnHostWriter.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Write-HostWriters/Write-InvokeCommandReturnHostWriter.ps1 -#v21.01.22.2212 -Function Write-InvokeCommandReturnHostWriter { - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($InvokeCommandReturnWriteArray) { - $hashTable = @{"Host" = ("[Remote Server: {0}] : {1}" -f $env:COMPUTERNAME, $WriteString) } - Set-Variable stringArray -Value ($Script:stringArray += $hashTable) -Scope Script - } else { - Write-HostWriter $WriteString - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnVerboseWriter.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnVerboseWriter.ps1 deleted file mode 100644 index c572cad02f..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-InvokeCommandReturnVerboseWriter.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Write-VerboseWriters/Write-InvokeCommandReturnVerboseWriter.ps1 -#v21.01.22.2212 -Function Write-InvokeCommandReturnVerboseWriter { - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($InvokeCommandReturnWriteArray) { - $hashTable = @{"Verbose" = ("[Remote Server: {0}] : {1}" -f $env:COMPUTERNAME, $WriteString) } - Set-Variable stringArray -Value ($Script:stringArray += $hashTable) -Scope Script - } else { - Write-VerboseWriter($WriteString) - } -} diff --git a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-ScriptMethodHostWriter.ps1 b/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-ScriptMethodHostWriter.ps1 deleted file mode 100644 index 20225dd809..0000000000 --- a/Diagnostics/ExchangeLogCollector/RemoteScriptBlock/extern/Write-ScriptMethodHostWriter.ps1 +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Write-HostWriters/Write-ScriptMethodHostWriter.ps1 -#v21.01.22.2212 -Function Write-ScriptMethodHostWriter { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Need to use Write Host')] - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($null -ne $this.LoggerObject) { - $this.LoggerObject.WriteHost($WriteString) - } elseif ($null -eq $this.HostFunctionCaller) { - Write-Host $WriteString - } else { - $this.HostFunctionCaller($WriteString) - } -} diff --git a/Diagnostics/ExchangeLogCollector/Write/Get-WritersToAddToScriptBlock.ps1 b/Diagnostics/ExchangeLogCollector/Write/Get-WritersToAddToScriptBlock.ps1 deleted file mode 100644 index 9094f06bfd..0000000000 --- a/Diagnostics/ExchangeLogCollector/Write/Get-WritersToAddToScriptBlock.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Get-WritersToAddToScriptBlock { - - $writersString = "Function Write-InvokeCommandReturnHostWriter { " + (${Function:Write-InvokeCommandReturnHostWriter}).ToString() + " } `n`n Function Write-InvokeCommandReturnVerboseWriter { " + (${Function:Write-InvokeCommandReturnVerboseWriter}).ToString() + " } `n`n#" - return $writersString -} diff --git a/Diagnostics/ExchangeLogCollector/Write/Write-DataOnlyOnceOnMasterServer.ps1 b/Diagnostics/ExchangeLogCollector/Write/Write-DataOnlyOnceOnMasterServer.ps1 index bc145e07ec..0ce9abf8c1 100644 --- a/Diagnostics/ExchangeLogCollector/Write/Write-DataOnlyOnceOnMasterServer.ps1 +++ b/Diagnostics/ExchangeLogCollector/Write/Write-DataOnlyOnceOnMasterServer.ps1 @@ -1,11 +1,14 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\ExchangeServerInfo\Get-VirtualDirectoriesLdap.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\New-Folder.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Save-DataInfoToFile.ps1 Function Write-DataOnlyOnceOnMasterServer { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseUsingScopeModifierInNewRunspaces', '', Justification = 'Can not use using for an env variable')] param() - Write-ScriptDebug("Enter Function: Write-DataOnlyOnceOnMasterServer") - Write-ScriptDebug("Writing only once data") + Write-Verbose("Enter Function: Write-DataOnlyOnceOnMasterServer") + Write-Verbose("Writing only once data") if (!$Script:MasterServer.ToUpper().Contains($env:COMPUTERNAME.ToUpper())) { $serverName = Invoke-Command -ComputerName $Script:MasterServer -ScriptBlock { return $env:COMPUTERNAME } @@ -43,8 +46,8 @@ Function Write-DataOnlyOnceOnMasterServer { Save-DataInfoToFile -DataIn $Error -SaveToLocation ("$RootCopyToDirectory\AllErrors") Save-DataInfoToFile -DataIn $Script:ErrorsHandled -SaveToLocation ("$RootCopyToDirectory\HandledErrors") } else { - Write-ScriptDebug ("No errors occurred within the script") + Write-Verbose ("No errors occurred within the script") } - Write-ScriptDebug("Exiting Function: Write-DataOnlyOnceOnMasterServer") + Write-Verbose("Exiting Function: Write-DataOnlyOnceOnMasterServer") } diff --git a/Diagnostics/ExchangeLogCollector/Write/Write-LargeDataObjectsOnMachine.ps1 b/Diagnostics/ExchangeLogCollector/Write/Write-LargeDataObjectsOnMachine.ps1 index 738587d3c3..37379c34ce 100644 --- a/Diagnostics/ExchangeLogCollector/Write/Write-LargeDataObjectsOnMachine.ps1 +++ b/Diagnostics/ExchangeLogCollector/Write/Write-LargeDataObjectsOnMachine.ps1 @@ -1,12 +1,22 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\ExchangeServerInfo\Get-DAGInformation.ps1 +. $PSScriptRoot\..\ExchangeServerInfo\Get-ExchangeBasicServerObject.ps1 +. $PSScriptRoot\..\Helpers\Add-ScriptBlockInjection.ps1 +. $PSScriptRoot\..\Helpers\PipelineFunctions.ps1 +. $PSScriptRoot\..\Helpers\Start-JobManager.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\Get-ExchangeInstallDirectory.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Compress-Folder.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Invoke-CatchBlockActions.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\New-Folder.ps1 +. $PSScriptRoot\..\RemoteScriptBlock\IO\Save-DataToFile.ps1 #This function job is to write out the Data that is too large to pass into the main script block #This is for mostly Exchange Related objects. #To handle this, we export the data locally and copy the data over the correct server. Function Write-LargeDataObjectsOnMachine { - Write-ScriptDebug("Function Enter Write-LargeDataObjectsOnMachine") + Write-Verbose("Function Enter Write-LargeDataObjectsOnMachine") [array]$serverNames = $Script:ArgumentList.ServerObjects | ForEach-Object { @@ -16,11 +26,15 @@ Function Write-LargeDataObjectsOnMachine { #Collect the Exchange Data that resides on their own machine. Function Invoke-ExchangeResideDataCollectionWrite { param( - [Parameter(Mandatory = $true)][object]$PassedInfo + [Parameter(Mandatory = $true, Position = 1)] + [string]$SaveToLocation, + + [Parameter(Mandatory = $true, Position = 2)] + [string]$InstallDirectory ) - $location = $PassedInfo.SaveToLocation - $exchBin = "{0}\Bin" -f $PassedInfo.InstallDirectory + $location = $SaveToLocation + $exchBin = "{0}\Bin" -f $InstallDirectory $configFiles = Get-ChildItem $exchBin | Where-Object { $_.Name -like "*.config" } $copyTo = "{0}\Config" -f $location $configFiles | ForEach-Object { Copy-Item $_.VersionInfo.FileName $copyTo } @@ -218,11 +232,11 @@ Function Write-LargeDataObjectsOnMachine { $dagWriteInformation | ForEach-Object { $location = "{0}{1}" -f $Script:RootFilePath, $_.ServerName - Write-ScriptDebug("Location of the data should be at: $location") + Write-Verbose("Location of the data should be at: $location") $remoteLocation = "\\{0}\{1}" -f $_.ServerName, $location.Replace(":", "$") - Write-ScriptDebug("Remote Copy Location: $remoteLocation") + Write-Verbose("Remote Copy Location: $remoteLocation") $rootTempLocation = "{0}{1}\{2}_Exchange_DAG_Information\" -f $localServerTempLocation, $_.ServerName, $_.DAGInfo.Name - Write-ScriptDebug("Local Root Temp Location: $rootTempLocation") + Write-Verbose("Local Root Temp Location: $rootTempLocation") New-Folder -NewFolders $rootTempLocation $_ | Add-Member -MemberType NoteProperty -Name RootSaveToLocation -Value $rootTempLocation Write-DatabaseAvailabilityGroupDataLocal -DAGWriteInfo $_ @@ -231,7 +245,7 @@ Function Write-LargeDataObjectsOnMachine { try { Copy-Item $zipCopyLocation $remoteLocation } catch { - Write-ScriptDebug("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") + Write-Verbose("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") Invoke-CatchBlockActions } } @@ -256,13 +270,13 @@ Function Write-LargeDataObjectsOnMachine { New-Folder -NewFolders $reportPath try { - Write-ScriptHost("Attempting to run CollectOverMetrics.ps1 against $($_.Name)") + Write-Host "Attempting to run CollectOverMetrics.ps1 against $($_.Name)" &"$Script:localExInstall\Scripts\CollectOverMetrics.ps1" -DatabaseAvailabilityGroup $_.Name ` -IncludeExtendedEvents ` -GenerateHtmlReport ` -ReportPath $reportPath } catch { - Write-ScriptDebug("Failed to collect failover metrics") + Write-Verbose("Failed to collect failover metrics") Invoke-CatchBlockActions $failed = $true } @@ -272,30 +286,30 @@ Function Write-LargeDataObjectsOnMachine { $_.Group | ForEach-Object { $location = "{0}{1}" -f $Script:RootFilePath, $_.ServerName - Write-ScriptDebug("Location of the data should be at: $location") + Write-Verbose("Location of the data should be at: $location") $remoteLocation = "\\{0}\{1}" -f $_.ServerName, $location.Replace(":", "$") - Write-ScriptDebug("Remote Copy Location: $remoteLocation") + Write-Verbose("Remote Copy Location: $remoteLocation") try { Copy-Item $zipCopyLocation $remoteLocation } catch { - Write-ScriptDebug("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") + Write-Verbose("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") Invoke-CatchBlockActions } } } else { - Write-ScriptDebug("Not compressing or copying over this folder.") + Write-Verbose("Not compressing or copying over this folder.") } } Remove-Item $localServerTempLocation -Recurse -Force } elseif ($null -eq $dagNameGroup -or $dagNameGroup.Count -eq 0) { - Write-ScriptDebug("No DAGs were found. Didn't run CollectOverMetrics.ps1") + Write-Verbose("No DAGs were found. Didn't run CollectOverMetrics.ps1") } elseif ($Script:EdgeRoleDetected) { - Write-ScriptHost("Unable to run CollectOverMetrics.ps1 script from an edge server") -ForegroundColor Yellow + Write-Host "Unable to run CollectOverMetrics.ps1 script from an edge server" -ForegroundColor Yellow } elseif ($CollectFailoverMetrics) { - Write-ScriptHost("Unable to run CollectOverMetrics.ps1 script from a remote shell session not on an Exchange Server or Tools box.") -ForegroundColor Yellow + Write-Host "Unable to run CollectOverMetrics.ps1 script from a remote shell session not on an Exchange Server or Tools box." -ForegroundColor Yellow } if ($ExchangeServerInformation) { @@ -353,15 +367,25 @@ Function Write-LargeDataObjectsOnMachine { Write out the Exchange Server Object Data and copy them over to the correct server #> + # Set remote version action to be able to return objects on the pipeline to log and handle them. + SetWriteRemoteVerboseAction "New-VerbosePipelineObject" + $scriptBlockInjectParams = @{ + IncludeScriptBlock = @(${Function:Write-Verbose}, ${Function:New-PipelineObject}, ${Function:New-VerbosePipelineObject}) + IncludeUsingParameter = "WriteRemoteVerboseDebugAction" + } #Setup all the Script blocks that we are going to use. - Write-ScriptDebug("Getting Get-ExchangeInstallDirectory string to create Script Block") - $getExchangeInstallDirectoryString = (${Function:Get-ExchangeInstallDirectory}).ToString().Replace("#Function Version", (Get-WritersToAddToScriptBlock)) - Write-ScriptDebug("Creating Script Block") + Write-Verbose("Getting Get-ExchangeInstallDirectory string to create Script Block") + $getExchangeInstallDirectoryString = Add-ScriptBlockInjection @scriptBlockInjectParams ` + -PrimaryScriptBlock ${Function:Get-ExchangeInstallDirectory} ` + -CatchActionFunction ${Function:Invoke-CatchBlockActions} + Write-Verbose("Creating Script Block") $getExchangeInstallDirectoryScriptBlock = [scriptblock]::Create($getExchangeInstallDirectoryString) - Write-ScriptDebug("Getting New-Folder string to create Script Block") - $newFolderString = (${Function:New-Folder}).ToString().Replace("#Function Version", (Get-WritersToAddToScriptBlock)) - Write-ScriptDebug("Creating script block") + Write-Verbose("Getting New-Folder string to create Script Block") + $newFolderString = Add-ScriptBlockInjection @scriptBlockInjectParams ` + -PrimaryScriptBlock ${Function:New-Folder} ` + -CatchActionFunction ${Function:Invoke-CatchBlockActions} + Write-Verbose("Creating script block") $newFolderScriptBlock = [scriptblock]::Create($newFolderString) $serverArgListExchangeInstallDirectory = @() @@ -375,30 +399,26 @@ Function Write-LargeDataObjectsOnMachine { $serverArgListExchangeInstallDirectory += [PSCustomObject]@{ ServerName = $serverName - ArgumentList = $true + ArgumentList = $null } $serverArgListDirectoriesToCreate += [PSCustomObject]@{ ServerName = $serverName - ArgumentList = [PSCustomObject]@{ - NewFolders = (@( - ("{0}{1}\Exchange_Server_Data\Config" -f $Script:RootFilePath, $serverName), - ("{0}{1}\Exchange_Server_Data\WebAppPools" -f $Script:RootFilePath, $serverName) - )) - } + ArgumentList = @(@("$Script:RootFilePath$serverName\Exchange_Server_Data\Config", "$Script:RootFilePath$serverName\Exchange_Server_Data\WebAppPools"), $false) } } - Write-ScriptDebug ("Calling job for Get Exchange Install Directory") - $serverInstallDirectories = Start-JobManager -ServersWithArguments $serverArgListExchangeInstallDirectory -ScriptBlock $getExchangeInstallDirectoryScriptBlock ` + Write-Verbose ("Calling job for Get Exchange Install Directory") + $serverInstallDirectories = Start-JobManager -ServersWithArguments $serverArgListExchangeInstallDirectory ` + -ScriptBlock $getExchangeInstallDirectoryScriptBlock ` -NeedReturnData $true ` - -DisplayReceiveJobInCorrectFunction $true ` - -JobBatchName "Exchange Install Directories for Write-LargeDataObjectsOnMachine" + -JobBatchName "Exchange Install Directories for Write-LargeDataObjectsOnMachine" ` + -RemotePipelineHandler ${Function:Invoke-PipelineHandler} - Write-ScriptDebug("Calling job for folder creation") + Write-Verbose("Calling job for folder creation") Start-JobManager -ServersWithArguments $serverArgListDirectoriesToCreate -ScriptBlock $newFolderScriptBlock ` - -DisplayReceiveJobInCorrectFunction $true ` - -JobBatchName "Creating folders for Write-LargeDataObjectsOnMachine" + -JobBatchName "Creating folders for Write-LargeDataObjectsOnMachine" ` + -RemotePipelineHandler ${Function:Invoke-PipelineHandler} #Now do the rest of the actions foreach ($serverData in $exchangeServerData) { @@ -407,19 +427,16 @@ Function Write-LargeDataObjectsOnMachine { $saveToLocation = "{0}{1}\Exchange_Server_Data" -f $Script:RootFilePath, $serverName $serverArgListExchangeResideData += [PSCustomObject]@{ ServerName = $serverName - ArgumentList = [PSCustomObject]@{ - SaveToLocation = $saveToLocation - InstallDirectory = $serverInstallDirectories[$serverName] - } + ArgumentList = @($saveToLocation, $serverInstallDirectories[$serverName]) } #Write out the Exchange object data locally as a temp and copy it over to the remote server $location = "{0}{1}\Exchange_Server_Data" -f $Script:RootFilePath, $serverName - Write-ScriptDebug("Location of data should be at: {0}" -f $location) + Write-Verbose("Location of data should be at: {0}" -f $location) $remoteLocation = "\\{0}\{1}" -f $serverName, $location.Replace(":", "$") - Write-ScriptDebug("Remote Copy Location: {0}" -f $remoteLocation) + Write-Verbose("Remote Copy Location: {0}" -f $remoteLocation) $rootTempLocation = "{0}{1}" -f $localServerTempLocation, $serverName - Write-ScriptDebug("Local Root Temp Location: {0}" -f $rootTempLocation) + Write-Verbose("Local Root Temp Location: {0}" -f $rootTempLocation) #Create the temp location and write out the data New-Folder -NewFolders $rootTempLocation Write-ExchangeObjectDataLocal -ServerData $serverData -Location $rootTempLocation @@ -428,7 +445,7 @@ Function Write-LargeDataObjectsOnMachine { try { Copy-Item $_.VersionInfo.FileName $remoteLocation } catch { - Write-ScriptDebug("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") + Write-Verbose("Failed to copy data to $remoteLocation. This is likely due to file sharing permissions.") Invoke-CatchBlockActions } } @@ -437,7 +454,7 @@ Function Write-LargeDataObjectsOnMachine { #Remove the temp data location right away Remove-Item $localServerTempLocation -Force -Recurse - Write-ScriptDebug("Calling Invoke-ExchangeResideDataCollectionWrite") + Write-Verbose("Calling Invoke-ExchangeResideDataCollectionWrite") Start-JobManager -ServersWithArguments $serverArgListExchangeResideData -ScriptBlock ${Function:Invoke-ExchangeResideDataCollectionWrite} ` -DisplayReceiveJob $false ` -JobBatchName "Write the data for Write-LargeDataObjectsOnMachine" @@ -451,13 +468,13 @@ Function Write-LargeDataObjectsOnMachine { New-Folder -NewFolders $createFolders -IncludeDisplayCreate $true Write-ExchangeObjectDataLocal -Location $location -ServerData $exchangeServerData - $passInfo = [PSCustomObject]@{ + $passInfo = @{ SaveToLocation = $location InstallDirectory = $ExInstall } - Write-ScriptDebug("Writing out the Exchange data") - Invoke-ExchangeResideDataCollectionWrite -PassedInfo $passInfo + Write-Verbose("Writing out the Exchange data") + Invoke-ExchangeResideDataCollectionWrite @passInfo } } } diff --git a/Diagnostics/ExchangeLogCollector/extern/Start-JobManager.ps1 b/Diagnostics/ExchangeLogCollector/extern/Start-JobManager.ps1 deleted file mode 100644 index aeb474872a..0000000000 --- a/Diagnostics/ExchangeLogCollector/extern/Start-JobManager.ps1 +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Start-JobManager/Start-JobManager.ps1 -#v21.01.22.2234 -Function Start-JobManager { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'I prefer Start here')] - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)][array]$ServersWithArguments, - [Parameter(Mandatory = $true)][scriptblock]$ScriptBlock, - [Parameter(Mandatory = $false)][string]$JobBatchName, - [Parameter(Mandatory = $false)][bool]$DisplayReceiveJob = $true, - [Parameter(Mandatory = $false)][bool]$DisplayReceiveJobInVerboseFunction, - [Parameter(Mandatory = $false)][bool]$DisplayReceiveJobInCorrectFunction, - [Parameter(Mandatory = $false)][bool]$NeedReturnData = $false - ) - #Function Version #v21.01.22.2234 - <# - [array]ServersWithArguments - [string]ServerName - [object]ArgumentList #customized for your scriptblock - #> - - Function Write-ReceiveJobData { - param( - [Parameter(Mandatory = $true)][array]$ReceiveJobData - ) - $returnJob = [string]::Empty - foreach ($job in $ReceiveJobData) { - if ($job["Verbose"]) { - Write-VerboseWriter($job["Verbose"]) - } elseif ($job["Host"]) { - Write-HostWriter($job["Host"]) - } elseif ($job["ReturnObject"]) { - $returnJob = $job["ReturnObject"] - } else { - Write-VerboseWriter("Unable to determine the key for the return type.") - } - } - return $returnJob - } - - Function Start-Jobs { - Write-VerboseWriter("Calling Start-Jobs") - foreach ($serverObject in $ServersWithArguments) { - $server = $serverObject.ServerName - $argumentList = $serverObject.ArgumentList - Write-VerboseWriter("Starting job on server {0}" -f $server) - Invoke-Command -ComputerName $server -ScriptBlock $ScriptBlock -ArgumentList $argumentList -AsJob -JobName $server | Out-Null - } - } - - Function Confirm-JobsPending { - $jobs = Get-Job - if ($null -ne $jobs) { - return $true - } - return $false - } - - Function Wait-JobsCompleted { - Write-VerboseWriter("Calling Wait-JobsCompleted") - [System.Diagnostics.Stopwatch]$timer = [System.Diagnostics.Stopwatch]::StartNew() - $returnData = @{} - while (Confirm-JobsPending) { - $completedJobs = Get-Job | Where-Object { $_.State -ne "Running" } - if ($null -eq $completedJobs) { - Start-Sleep 1 - continue - } - - foreach ($job in $completedJobs) { - $receiveJobNull = $false - $jobName = $job.Name - Write-VerboseWriter("Job {0} received. State: {1} | HasMoreData: {2}" -f $job.Name, $job.State, $job.HasMoreData) - if ($NeedReturnData -eq $false -and $DisplayReceiveJob -eq $false -and $job.HasMoreData -eq $true) { - Write-VerboseWriter("This job has data and you provided you didn't want to return it or display it.") - } - $receiveJob = Receive-Job $job - Remove-Job $job - if ($null -eq $receiveJob) { - $receiveJobNull = $True - Write-VerboseWriter("Job {0} didn't have any receive job data" -f $jobName) - } - if ($DisplayReceiveJobInVerboseFunction -and (-not($receiveJobNull))) { - Write-VerboseWriter("[JobName: {0}] : {1}" -f $jobName, $receiveJob) - } elseif ($DisplayReceiveJobInCorrectFunction -and (-not ($receiveJobNull))) { - $returnJobData = Write-ReceiveJobData -ReceiveJobData $receiveJob - if ($null -ne $returnJobData) { - $returnData.Add($jobName, $returnJobData) - } - } elseif ($DisplayReceiveJob -and (-not($receiveJobNull))) { - Write-HostWriter $receiveJob - } - if ($NeedReturnData -and (-not($DisplayReceiveJobInCorrectFunction))) { - $returnData.Add($job.Name, $receiveJob) - } - } - } - $timer.Stop() - Write-VerboseWriter("Waiting for jobs to complete took {0} seconds" -f $timer.Elapsed.TotalSeconds) - if ($NeedReturnData) { - return $returnData - } - return $null - } - - [System.Diagnostics.Stopwatch]$timerMain = [System.Diagnostics.Stopwatch]::StartNew() - Write-VerboseWriter("Calling Start-JobManager") - Write-VerboseWriter("Passed: [bool]DisplayReceiveJob: {0} | [string]JobBatchName: {1} | [bool]DisplayReceiveJobInVerboseFunction: {2} | [bool]NeedReturnData:{3}" -f $DisplayReceiveJob, - $JobBatchName, - $DisplayReceiveJobInVerboseFunction, - $NeedReturnData) - - Start-Jobs - $data = Wait-JobsCompleted - $timerMain.Stop() - Write-VerboseWriter("Exiting: Start-JobManager | Time in Start-JobManager: {0} seconds" -f $timerMain.Elapsed.TotalSeconds) - if ($NeedReturnData) { - return $data - } - return $null -} diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 index 5b61295ca8..4a2fb5f2be 100644 --- a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 +++ b/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeInformation.ps1 @@ -1,13 +1,13 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeBuildVersionInformation.ps1 . $PSScriptRoot\..\..\..\..\Shared\Get-RemoteRegistryValue.ps1 . $PSScriptRoot\..\..\..\..\Shared\Invoke-ScriptBlockHandler.ps1 . $PSScriptRoot\..\..\Helpers\Invoke-CatchActions.ps1 . $PSScriptRoot\Get-ExchangeAdSchemaClass.ps1 . $PSScriptRoot\Get-ExchangeApplicationConfigurationFileValidation.ps1 . $PSScriptRoot\Get-ExchangeAppPoolsInformation.ps1 -. $PSScriptRoot\Get-ExchangeBuildVersionInformation.ps1 . $PSScriptRoot\Get-ExchangeEmergencyMitigationServiceState.ps1 . $PSScriptRoot\Get-ExchangeAMSIConfigurationState.ps1 . $PSScriptRoot\Get-FIPFSScanEngineVersionState.ps1 diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeBuildVersionInformation.ps1 b/Shared/Get-ExchangeBuildVersionInformation.ps1 similarity index 100% rename from Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeBuildVersionInformation.ps1 rename to Shared/Get-ExchangeBuildVersionInformation.ps1 diff --git a/Shared/Invoke-ScriptBlockHandler.ps1 b/Shared/Invoke-ScriptBlockHandler.ps1 index 1baf424bc1..86fc5919c7 100644 --- a/Shared/Invoke-ScriptBlockHandler.ps1 +++ b/Shared/Invoke-ScriptBlockHandler.ps1 @@ -3,6 +3,8 @@ . $PSScriptRoot\Invoke-CatchActionError.ps1 +# Common method used to handle Invoke-Command within a script. +# Avoids using Invoke-Command when running locally on a server. Function Invoke-ScriptBlockHandler { [CmdletBinding()] param( diff --git a/Shared/LoggerFunctions.ps1 b/Shared/LoggerFunctions.ps1 index 743f5984c8..5bcd8b38f8 100644 --- a/Shared/LoggerFunctions.ps1 +++ b/Shared/LoggerFunctions.ps1 @@ -4,7 +4,6 @@ Function Get-NewLoggerInstance { [CmdletBinding()] param( - [ValidateScript( { Test-Path $_ })] [string]$LogDirectory = (Get-Location).Path, [ValidateNotNullOrEmpty()] @@ -24,6 +23,14 @@ Function Get-NewLoggerInstance { $fileName = if ($AppendDateTimeToFileName) { "{0}_{1}.txt" -f $LogName, ((Get-Date).ToString('yyyyMMddHHmmss')) } else { "$LogName.txt" } $fullFilePath = [System.IO.Path]::Combine($LogDirectory, $fileName) + if (-not (Test-Path $LogDirectory)) { + try { + New-Item -ItemType Directory -Path $LogDirectory -ErrorAction Stop | Out-Null + } catch { + throw "Failed to create Log Directory: $LogDirectory" + } + } + return [PSCustomObject]@{ FullPath = $fullFilePath AppendDateTime = $AppendDateTime diff --git a/Shared/New-LoggerObject.ps1 b/Shared/New-LoggerObject.ps1 deleted file mode 100644 index d3db5eaab2..0000000000 --- a/Shared/New-LoggerObject.ps1 +++ /dev/null @@ -1,249 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/New-LoggerObject/New-LoggerObject.ps1 -#v21.01.22.2234 -Function New-LoggerObject { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'I prefer New here')] - [CmdletBinding()] - param( - [Parameter(Mandatory = $false)][string]$LogDirectory = ".", - [Parameter(Mandatory = $false)][string]$LogName = "Script_Logging", - [Parameter(Mandatory = $false)][bool]$EnableDateTime = $true, - [Parameter(Mandatory = $false)][bool]$IncludeDateTimeToFileName = $true, - [Parameter(Mandatory = $false)][int]$MaxFileSizeInMB = 10, - [Parameter(Mandatory = $false)][int]$CheckSizeIntervalMinutes = 10, - [Parameter(Mandatory = $false)][int]$NumberOfLogsToKeep = 10, - [Parameter(Mandatory = $false)][bool]$VerboseEnabled, - [Parameter(Mandatory = $false)][scriptblock]$HostFunctionCaller, - [Parameter(Mandatory = $false)][scriptblock]$VerboseFunctionCaller - ) - #Function Version #v21.01.22.2234 - - ######################## - # - # Template Functions - # - ######################## - - Function Write-ToLog { - param( - [object]$WriteString, - [string]$LogLocation - ) - $WriteString | Out-File ($LogLocation) -Append - } - - ######################## - # - # End Template Functions - # - ######################## - - ########## Parameter Binding Exceptions ############## - if ($LogDirectory -eq ".") { - $LogDirectory = (Get-Location).Path - } - - if ([string]::IsNullOrWhiteSpace($LogName)) { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid LogName" - } - - if (!(Test-Path $LogDirectory)) { - - try { - New-Item -Path $LogDirectory -ItemType Directory | Out-Null - } catch { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid LogDirectory" - } - } - - $loggerObject = New-Object PSCustomObject - $loggerObject | Add-Member -MemberType NoteProperty -Name "FileDirectory" -Value $LogDirectory - $loggerObject | Add-Member -MemberType NoteProperty -Name "FileName" -Value $LogName - $loggerObject | Add-Member -MemberType NoteProperty -Name "FullPath" -Value $fullLogPath - $loggerObject | Add-Member -MemberType NoteProperty -Name "InstanceBaseName" -Value ([string]::Empty) - $loggerObject | Add-Member -MemberType NoteProperty -Name "EnableDateTime" -Value $EnableDateTime - $loggerObject | Add-Member -MemberType NoteProperty -Name "IncludeDateTimeToFileName" -Value $IncludeDateTimeToFileName - $loggerObject | Add-Member -MemberType NoteProperty -Name "MaxFileSizeInMB" -Value $MaxFileSizeInMB - $loggerObject | Add-Member -MemberType NoteProperty -Name "CheckSizeIntervalMinutes" -Value $CheckSizeIntervalMinutes - $loggerObject | Add-Member -MemberType NoteProperty -Name "NextFileCheckTime" -Value ((Get-Date).AddMinutes($CheckSizeIntervalMinutes)) - $loggerObject | Add-Member -MemberType NoteProperty -Name "InstanceNumber" -Value 1 - $loggerObject | Add-Member -MemberType NoteProperty -Name "NumberOfLogsToKeep" -Value $NumberOfLogsToKeep - $loggerObject | Add-Member -MemberType NoteProperty -Name "WriteVerboseData" -Value $VerboseEnabled - $loggerObject | Add-Member -MemberType NoteProperty -Name "PreventLogCleanup" -Value $false - $loggerObject | Add-Member -MemberType NoteProperty -Name "LoggerDisabled" -Value $false - $loggerObject | Add-Member -MemberType ScriptMethod -Name "ToLog" -Value ${Function:Write-ToLog} - $loggerObject | Add-Member -MemberType ScriptMethod -Name "WriteHostWriter" -Value ${Function:Write-ScriptMethodHostWriter} - $loggerObject | Add-Member -MemberType ScriptMethod -Name "WriteVerboseWriter" -Value ${Function:Write-ScriptMethodVerboseWriter} - - if ($null -ne $HostFunctionCaller) { - $loggerObject | Add-Member -MemberType ScriptMethod -Name "HostFunctionCaller" -Value $HostFunctionCaller - } - - if ($null -ne $VerboseFunctionCaller) { - $loggerObject | Add-Member -MemberType ScriptMethod -Name "VerboseFunctionCaller" -Value $VerboseFunctionCaller - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "WriteHost" -Value { - param( - [object]$LoggingString - ) - - if ($this.LoggerDisabled) { - return - } - - if ($null -eq $LoggingString) { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid LoggingString" - } - - if ($this.EnableDateTime) { - $LoggingString = "[{0}] : {1}" -f [System.DateTime]::Now, $LoggingString - } - - $this.WriteHostWriter($LoggingString) - $this.ToLog($LoggingString, $this.FullPath) - $this.LogUpKeep() - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "WriteVerbose" -Value { - param( - [object]$LoggingString - ) - - if ($this.LoggerDisabled) { - return - } - - if ($null -eq $LoggingString) { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid LoggingString" - } - - if ($this.EnableDateTime) { - $LoggingString = "[{0}] : {1}" -f [System.DateTime]::Now, $LoggingString - } - $this.WriteVerboseWriter($LoggingString) - $this.ToLog($LoggingString, $this.FullPath) - $this.LogUpKeep() - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "WriteToFileOnly" -Value { - param( - [object]$LoggingString - ) - - if ($this.LoggerDisabled) { - return - } - - if ($null -eq $LoggingString) { - throw [System.Management.Automation.ParameterBindingException] "Failed to provide valid LoggingString" - } - - if ($this.EnableDateTime) { - $LoggingString = "[{0}] : {1}" -f [System.DateTime]::Now, $LoggingString - } - $this.ToLog($LoggingString, $this.FullPath) - $this.LogUpKeep() - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "UpdateFileLocation" -Value { - - if ($this.LoggerDisabled) { - return - } - - if ($null -eq $this.FullPath) { - - if ($this.IncludeDateTimeToFileName) { - $this.InstanceBaseName = "{0}_{1}" -f $this.FileName, ((Get-Date).ToString('yyyyMMddHHmmss')) - $this.FullPath = "{0}\{1}.txt" -f $this.FileDirectory, $this.InstanceBaseName - } else { - $this.InstanceBaseName = "{0}" -f $this.FileName - $this.FullPath = "{0}\{1}.txt" -f $this.FileDirectory, $this.InstanceBaseName - } - } else { - - do { - $this.FullPath = "{0}\{1}_{2}.txt" -f $this.FileDirectory, $this.InstanceBaseName, $this.InstanceNumber - $this.InstanceNumber++ - }while (Test-Path $this.FullPath) - $this.WriteVerbose("Updated to New Log") - } - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "LogUpKeep" -Value { - - if ($this.LoggerDisabled) { - return - } - - if ($this.NextFileCheckTime -gt [System.DateTime]::Now) { - return - } - $this.NextFileCheckTime = (Get-Date).AddMinutes($this.CheckSizeIntervalMinutes) - $this.CheckFileSize() - $this.CheckNumberOfFiles() - $this.WriteVerbose("Did Log Object Up Keep") - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "CheckFileSize" -Value { - - if ($this.LoggerDisabled) { - return - } - - $item = Get-ChildItem $this.FullPath - - if (($item.Length / 1MB) -gt $this.MaxFileSizeInMB) { - $this.UpdateFileLocation() - } - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "CheckNumberOfFiles" -Value { - - if ($this.LoggerDisabled) { - return - } - - $filter = "{0}*" -f $this.InstanceBaseName - $items = Get-ChildItem -Path $this.FileDirectory | Where-Object { $_.Name -like $filter } - - if ($items.Count -gt $this.NumberOfLogsToKeep) { - do { - $items | Sort-Object LastWriteTime | Select-Object -First 1 | Remove-Item -Force - $items = Get-ChildItem -Path $this.FileDirectory | Where-Object { $_.Name -like $filter } - }while ($items.Count -gt $this.NumberOfLogsToKeep) - } - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "RemoveLatestLogFile" -Value { - - if ($this.LoggerDisabled) { - return - } - - if (!$this.PreventLogCleanup) { - $item = Get-ChildItem $this.FullPath - Remove-Item $item -Force - } - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "DisableLogger" -Value { - $this.LoggerDisabled = $true - } - - $loggerObject | Add-Member -MemberType ScriptMethod -Name "EnableLogger" -Value { - $this.LoggerDisabled = $false - } - - $loggerObject.UpdateFileLocation() - try { - "[{0}] : Creating a new logger instance" -f [System.DAteTime]::Now | Out-File ($loggerObject.FullPath) -Append - } catch { - throw - } - - return $loggerObject -} diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Tests/E19CU11AdminDisplayVersion.xml b/Shared/Tests/E19CU11AdminDisplayVersion.xml similarity index 100% rename from Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Tests/E19CU11AdminDisplayVersion.xml rename to Shared/Tests/E19CU11AdminDisplayVersion.xml diff --git a/Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Tests/Get-ExchangeBuildVersionInformation.Tests.ps1 b/Shared/Tests/Get-ExchangeBuildVersionInformation.Tests.ps1 similarity index 100% rename from Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Tests/Get-ExchangeBuildVersionInformation.Tests.ps1 rename to Shared/Tests/Get-ExchangeBuildVersionInformation.Tests.ps1 diff --git a/Shared/Write-Host.ps1 b/Shared/Write-Host.ps1 index c3f517bc34..73c99bfad0 100644 --- a/Shared/Write-Host.ps1 +++ b/Shared/Write-Host.ps1 @@ -5,19 +5,22 @@ Function Write-Host { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification = 'Proper handling of write host with colors')] [CmdletBinding()] param( - [Parameter(Position = 1)] + [Parameter(Position = 1, ValueFromPipeline)] [object]$Object, [switch]$NoNewLine, [string]$ForegroundColor ) - begin { + process { $consoleHost = $host.Name -eq "ConsoleHost" + + if ($null -ne $Script:WriteHostManipulateObjectAction) { + $Object = & $Script:WriteHostManipulateObjectAction $Object + } + $params = @{ Object = $Object NoNewLine = $NoNewLine } - } - process { if ([string]::IsNullOrEmpty($ForegroundColor)) { if ($null -ne $host.UI.RawUI.ForegroundColor -and @@ -72,3 +75,7 @@ Function RevertProperForegroundColor { Function SetWriteHostAction ($DebugAction) { $Script:WriteHostDebugAction = $DebugAction } + +Function SetWriteHostManipulateObjectAction ($ManipulateObject) { + $Script:WriteHostManipulateObjectAction = $ManipulateObject +} diff --git a/Shared/Write-HostWriter.ps1 b/Shared/Write-HostWriter.ps1 deleted file mode 100644 index a8f7def049..0000000000 --- a/Shared/Write-HostWriter.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Write-HostWriter { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Need to use Write Host')] - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($null -ne $Script:Logger) { - $Script:Logger.WriteHost($WriteString) - } elseif ($null -eq $HostFunctionCaller) { - Write-Host $WriteString - } else { - &$HostFunctionCaller $WriteString - } -} diff --git a/Shared/Write-ScriptMethodVerboseWriter.ps1 b/Shared/Write-ScriptMethodVerboseWriter.ps1 deleted file mode 100644 index 59b335ea53..0000000000 --- a/Shared/Write-ScriptMethodVerboseWriter.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -#https://github.com/dpaulson45/PublicPowerShellFunctions/blob/master/src/Common/Write-VerboseWriters/Write-ScriptMethodVerboseWriter.ps1 -#v21.01.22.2212 -Function Write-ScriptMethodVerboseWriter { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Need to use Write Host')] - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($null -ne $this.LoggerObject) { - $this.LoggerObject.WriteVerbose($WriteString) - } elseif ($null -eq $this.VerboseFunctionCaller -and - $this.WriteVerboseData) { - Write-Host $WriteString -ForegroundColor Cyan - } elseif ($this.WriteVerboseData) { - $this.VerboseFunctionCaller($WriteString) - } -} diff --git a/Shared/Write-VerboseWriter.ps1 b/Shared/Write-VerboseWriter.ps1 deleted file mode 100644 index 864364df9e..0000000000 --- a/Shared/Write-VerboseWriter.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -Function Write-VerboseWriter { - param( - [Parameter(Mandatory = $true)][string]$WriteString - ) - if ($null -ne $Script:Logger) { - $Script:Logger.WriteVerbose($WriteString) - } elseif ($null -eq $VerboseFunctionCaller) { - Write-Verbose $WriteString - } else { - &$VerboseFunctionCaller $WriteString - } -}