Support/ERCS_Logs/ERCS_AzureStackLogs.ps1 (1,654 lines of code) (raw):

<# .SYNOPSIS Built to be run on the HLH, DVM, or Jumpbox from an administrative powershell session the script uses seven methods to find the privileged endpoint virtual machines. The script connects to selected privileged endpoint and runs Get-AzureStackLog with supplied parameters. If no parameters are supplied the script will default to prompting user via GUI for needed parameters. .DESCRIPTION The script will use one of the below seven methods; Gather requested logs, Transcript, and AzureStackStampInformation.json. The script will also save AzureStackStampInformation.json in %ProgramData% and in created log folder. AzureStackStampInformation.json in %ProgramData% allows future runs to have ERCS IP information populated at beginning of script. Methods: Check %ProgramData% for AzureStackStampInformation.json Prompt user for AzureStackStampInformation.json Prompt user for install prefix and check connection to privileged endpoint virtual machine(s) Install and/or load AD powershell module and check for computernames that match ERCS Install and/or load DNS powershell module and check for A records in all zones that that match ERCS Prompt user for tenant portal and based of the IP address of the portal find the likely IP(s) of privileged endpoint virtual machine(s) Prompt user for manual entry of IP address of a privileged endpoint virtual machine .PARAMETER FromDate Specifies starting time frame for data search. If parameter is not specified, script will default to 4 hours from current time. Format must be in one of the 3 formats: (get-date).AddHours(-4) "MM/DD/YYYY HH:MM" "MM/DD/YYYY" .PARAMETER ToDate Specifies ending time frame for data search. If parameter is not specified, script will default to current time. Format must be in one of the 3 formats: (get-date).AddHours(-1) "MM/DD/YYYY HH:MM" "MM/DD/YYYY" .PARAMETER Scenario Built for future use .PARAMETER FilterByRole Specifies parameter to filter log collection. Valid formats are comma separated values. List of possible switches http://aka.ms/AzureStack/Diagnostics .PARAMETER ErcsName Specifies privileged endpoint virtual machine name or IP address to use. Example: AzS-ERCS01 or 192.168.200.255 .PARAMETER AzSCredentials Specifies credentials the script will use to connect to Azure Stack privileged endpoint. Format must be in one of the 2 formats: (Get-Credential -Message "Azure Stack credentials") (Get-Credential) .PARAMETER ShareCred Specifies credentials the script will use to build a local share Format must be in one of the 2 formats: (Get-Credential -Message "Local share credentials" -UserName $env:USERNAME) (Get-Credential) .PARAMETER InStamp Specifies if script is running on Azure Stack machine such as Azure Stack Development Kit deployment or DVM. Yes No .PARAMETER StampTimeZone Specifies timezone id for Azure Stack stamp. Format must be in one of the 2 formats: (Get-TimeZone -Name "US Eastern*").id "Pacific Standard Time" .PARAMETER IncompleteDeployment Specifies if Azure Stack Deployment is incomplete. Only for use in Azure Stack Development Kit deployment or DVM Yes No .EXAMPLE .\ERCS_AzureStackLogs.ps1 -FromDate (get-date).AddHours(-4) -ToDate (get-date) -FilterByRole VirtualMachines,BareMetal -ErcsName AzS-ERCS01 -AzSCredentials (Get-Credential -Message "Azure Stack credentials") -ShareCred (get-credential -Message "Local share credentials" -UserName $env:USERNAME) -InStamp No -StampTimeZone "Pacific Standard Time" -IncompleteDeployment No #> Param( [Parameter(Mandatory=$false,HelpMessage="Valid formats 'MM/DD/YYYY' or 'MM/DD/YYYY HH:MM'")] [ValidateScript({$_ -lt (get-date)})] [DateTime] $FromDate, [Parameter(Mandatory=$false,HelpMessage="Valid formats are: in 'MM/DD/YYYY' or 'MM/DD/YYYY HH:MM'")] [DateTime] $ToDate, [Parameter(Mandatory=$false,HelpMessage="Valid formats are: in '(Get-TimeZone -Name 'US Eastern*').id' or 'Pacific Standard Time'")] [String] $StampTimeZone, [Parameter(Mandatory=$false,HelpMessage="Valid choices are: Service Fabric, Storage, Networking, Identity, Patch & Update, Compute, Backup")] [ValidateSet("Service Fabric", "Storage", "Networking", "Identity", "Patch & Update", "Compute", "Backup")] [string] $Scenario, [Parameter(Mandatory=$false,HelpMessage="FilterByRole parameter to filter log collection. Valid formats are comma separated values.")] [string[]]$FilterByRole, [Parameter(Mandatory=$false,HelpMessage="ERCS machine name or IP Address, Example: AzS-ERCS01 or 192.168.200.255")] [string]$ErcsName, [Parameter(Mandatory=$false,HelpMessage="Credentials the script will use to connect to Azure Stack privileged endpoint")] [PSCredential]$AzSCredentials, [Parameter(Mandatory=$false,HelpMessage="Credentials the script will use to build a local share")] [PSCredential]$ShareCred, [Parameter(Mandatory=$false,HelpMessage="Script is running on Azure Stack machine such as Azure Stack Development Kit deployment or DVM? Valid formats are: Yes or No")] [ValidateSet("Yes", "No")] [String] $InStamp, [Parameter(Mandatory=$false,HelpMessage="Has Deployment Completed? Valid formats are: Yes or No")] [ValidateSet("Yes", "No")] [String] $IncompleteDeployment ) #warn if running in the ISE do to .net ui rendering if ($psise -ne $null) { Write-Host "`n `t[WARN] Script should not be run from PowerShell ISE" -ForegroundColor Yellow Read-Host -Prompt "`tPress Enter to continue" } #Run as Admin $ScriptPath = $script:MyInvocation.MyCommand.Path # Check to see if we are in FullLanguage $LanguageMode = $ExecutionContext.SessionState.LanguageMode #load .net assembly Add-Type -AssemblyName System.DirectoryServices.AccountManagement # Get the ID and security principal of the current user account $myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent(); $myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID); # Get the security principal for the administrator role $adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator; # Check to see if we are currently running as an administrator if($myWindowsPrincipal.IsInRole($adminRole)) { # We are running as an administrator, so change the title to indicate this Write-Host "`n[SUCCESS] Script must be run from an Administrative Powershell Session `n" -ForegroundColor Green } else { # We are not running as an administrator so stop. Write-Host "`n `t [ERROR] Script must be run from an Administrative Powershell Session" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } # Check to see if we are currently running in FullLanguage if($LanguageMode -eq "FullLanguage") { # We are running in FullLanguage Write-Host "`n[SUCCESS] Script is running in FullLanguage Powershell Mode`n" -ForegroundColor Green } else { # We are not running in FullLanguage so stop. Write-Host "`n `t [ERROR] Script must be run in FullLanguage Powershell Mode" -ForegroundColor Red Write-Host "`n `tFor more information run `"Get-Help about_Language_Modes`" " Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } #------------------------------------------------------------------------------ # # Copyright © 2017 Microsoft Corporation. All rights reserved. # # THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT # WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT # LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS # FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR # RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. # #------------------------------------------------------------------------------ # # PowerShell Source Code # # NAME: # ERCS_AzureStackLogs # # VERSION: # 1.6.1 #------------------------------------------------------------------------------ "------------------------------------------------------------------------------ " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow " Copyright © 2017 Microsoft Corporation. All rights reserved. " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow " THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED `“AS IS`” WITHOUT " | Write-Host -ForegroundColor Yellow " WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT " | Write-Host -ForegroundColor Yellow " LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS " | Write-Host -ForegroundColor Yellow " FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR " | Write-Host -ForegroundColor Yellow " RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. " | Write-Host -ForegroundColor Yellow "------------------------------------------------------------------------------ " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow " PowerShell Source Code " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow " NAME: " | Write-Host -ForegroundColor Yellow " ERCS_AzureStackLogs.ps1 " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow " VERSION: " | Write-Host -ForegroundColor Yellow " 1.6.1" | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow "------------------------------------------------------------------------------ " | Write-Host -ForegroundColor Yellow "" | Write-Host -ForegroundColor Yellow "`n This script SAMPLE is provided and intended only to act as a SAMPLE ONLY," | Write-Host -ForegroundColor Yellow " and is NOT intended to serve as a solution to any known technical issue." | Write-Host -ForegroundColor Yellow "`n By executing this SAMPLE AS-IS, you agree to assume all risks and responsibility associated." | Write-Host -ForegroundColor Yellow $ErrorActionPreference = "SilentlyContinue" $ContinueAnswer = Read-Host "`n Do you wish to proceed at your own risk? (Y/N)" If ($ContinueAnswer -ne "Y") { Write-Host "`n Exiting." -ForegroundColor Red;Exit } #Start Up WinRm we need it later $winrm = Get-Service -Name winrm If ($winrm) { If($winrm.StartType -ne "Automatic") { #Start Up WinRm we need it later Write-Host "`n[INFO] Configuring Windows PowerShell for remoting" -ForegroundColor Green $PSRemoting = Invoke-Command -ComputerName localhost -ScriptBlock {Enable-PSRemoting -Force} -AsJob while((get-job -Id $PSRemoting.id).State -eq "Running") { $PSRper = (Get-Random -Minimum 5 -Maximum 80); Start-Sleep -Milliseconds 1500 Write-Progress -Activity "Please wait while Powershell Remoting is setup on $($env:COMPUTERNAME)" -PercentComplete $PSRper } if((get-job -Id $PSRemoting.id).State -eq "Completed") { Write-Progress -Activity "Please wait while Powershell Remoting is setup on $($env:COMPUTERNAME)" -Status "Ready" -Completed } } } #clear var $ip $IP = $null Clear-Host #Temp Firewall rule for access to PEP and SMB to allow file transfer from PEP Try { $FWruletest = Get-NetFirewallRule -Group "AzureStack_ERCS" -ErrorAction SilentlyContinue If(!($FWruletest)) { $firewall = New-NetFirewallRule -Name "AzureStack Firewall PEP rule" -DisplayName "AzureStack PEP Access Firewall rule" -Description "Allow Outbound Access to Remote Powershell" -Group "AzureStack_ERCS" -Enabled True -Action Allow -Profile Any -Direction Outbound -Protocol TCP -RemotePort 5985 $SMB = New-NetFirewallRule -Name "AzureStack Firewall SMB rule" -DisplayName "AzureStack SMB Access Firewall rule" -Description "Allow inbound Access to SMB Powershell" -Group "AzureStack_ERCS" -Enabled True -Action Allow -Profile Any -Direction Inbound -Protocol TCP -LocalPort 445 } If($firewall.PrimaryStatus -eq "OK") {Write-Host "`n `t[INFO] Created firewall rules to allow access to AzureStack" -ForegroundColor Green} } catch { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } #Test for Module function load_module($name) { if (-not(Get-Module -Name $name)) { if (Get-Module -ListAvailable | Where-Object { $_.name -eq $name }) { Import-Module $name return $true } else { return $false } } else { return $true } } #ERCS input check if ($ErcsName) { if(!($IP)) { $global:progresspreference ="SilentlyContinue" $ercstest = Test-NetConnection -port 5985 -ComputerName $ErcsName If ($ercstest.TcpTestSucceeded -eq "True"){$IP = $ercstest.RemoteAddress.IPAddressToString} $global:progresspreference ="Continue" } } #AutoAzureStackStampInformation If(!($IP)) { If ((Test-Path -Path "$($Env:ProgramData)\AzureStackStampInformation.json") -eq $true) { Write-Host "`n `t[INFO] Loaded AzureStackStampInformation.json from ProgramData" -ForegroundColor Green $FoundJSONFile = Get-Content -Raw -Path "$($Env:ProgramData)\AzureStackStampInformation.json" | ConvertFrom-Json [string]$FoundDomainFQDN = $FoundJSONFile.DomainFQDN [array]$ERCSIPS = $FoundJSONFile.EmergencyConsoleIPAddresses $StampTimeZone = $FoundJSONFile.Timezone $FoundSelERCSIP = $FoundJSONFile.EmergencyConsoleIPAddresses | Out-GridView -Title "Please Select Emergency Console IP Address" -PassThru $IP = $FoundSelERCSIP } If ((Test-Path -Path "$($Env:ProgramData)\AzureStackStampInformation.json") -eq $false) { if ((Test-Path -Path "$($env:SystemDrive)\CloudDeployment\Logs\AzureStackStampInformation.json") -eq $true) { Write-Host "`n `t[INFO] Loaded AzureStackStampInformation.json from CloudDeployment" -ForegroundColor Green $FoundJSONFile = Get-Content -Raw -Path "$($env:SystemDrive)\CloudDeployment\Logs\AzureStackStampInformation.json" | ConvertFrom-Json [string]$FoundDomainFQDN = $FoundJSONFile.DomainFQDN [array]$ERCSIPS = $FoundJSONFile.EmergencyConsoleIPAddresses $StampTimeZone = $FoundJSONFile.Timezone $FoundSelERCSIP = $FoundJSONFile.EmergencyConsoleIPAddresses | Out-GridView -Title "Please Select Emergency Console IP Address" -PassThru $IP = $FoundSelERCSIP } } } #Sel AzureStackStampInformation if(!($IP)) { #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $JSONMainForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.Label]$Jsonlabel = $null [System.Windows.Forms.Button]$JsonYbutton = $null [System.Windows.Forms.Button]$JsonNbutton = $null [System.Windows.Forms.Button]$button1 = $null $Jsonlabel = New-Object -TypeName System.Windows.Forms.Label $JsonYbutton = New-Object -TypeName System.Windows.Forms.Button $JsonNbutton = New-Object -TypeName System.Windows.Forms.Button $JSONMainForm.SuspendLayout() # #Jsonlabel # $Jsonlabel.AutoSize = $true $Jsonlabel.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(59,42) $Jsonlabel.Name = 'Jsonlabel' $Jsonlabel.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(248,13) $Jsonlabel.TabIndex = 0 $Jsonlabel.Text = 'Do you have the AzureStackStampInformation.json' # #JsonYbutton # $JsonYbutton.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(62,78) $JsonYbutton.Name = 'JsonYbutton' $JsonYbutton.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $JsonYbutton.TabIndex = 1 $JsonYbutton.Text = 'Yes' $JsonYbutton.UseVisualStyleBackColor = $true $JsonYbutton.DialogResult = [System.Windows.Forms.DialogResult]::Yes # #JsonNbutton # $JsonNbutton.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(232,78) $JsonNbutton.Name = 'JsonNbutton' $JsonNbutton.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $JsonNbutton.TabIndex = 2 $JsonNbutton.Text = 'No' $JsonNbutton.UseVisualStyleBackColor = $true $JsonNbutton.DialogResult = [System.Windows.Forms.DialogResult]::No # #JSONMainForm # $JSONMainForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(369,133) $JSONMainForm.Controls.Add($JsonNbutton) $JSONMainForm.Controls.Add($JsonYbutton) $JSONMainForm.Controls.Add($Jsonlabel) $JSONMainForm.Name = 'JSONMainForm' $JSONMainForm.ResumeLayout($false) $JSONMainForm.PerformLayout() Add-Member -InputObject $JSONMainForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $JSONMainForm -Name Jsonlabel -Value $Jsonlabel -MemberType NoteProperty Add-Member -InputObject $JSONMainForm -Name JsonYbutton -Value $JsonYbutton -MemberType NoteProperty Add-Member -InputObject $JSONMainForm -Name JsonNbutton -Value $JsonNbutton -MemberType NoteProperty Add-Member -InputObject $JSONMainForm -Name button1 -Value $button1 -MemberType NoteProperty $JSONMainForm.Topmost = $True $JSONMainForm.StartPosition = "CenterScreen" $JSONMainForm.MaximizeBox = $false $JSONMainForm.FormBorderStyle = 'Fixed3D' $result = $JSONMainForm.ShowDialog() #endregion .NET switch ($result) { "Yes" { Add-Type -AssemblyName System.Windows.Forms $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = $env:SystemDrive Filter = 'JSON File (*.json)|*.json' } [void]$FileBrowser.ShowDialog() $JSONFile = Get-Content -Raw -Path $FileBrowser.FileNames | ConvertFrom-Json If($JSONFile) { Write-Host "`n `t[INFO] Loaded $($FileBrowser.FileNames)" -ForegroundColor Green Write-Host "`n `t[INFO] Saving AzureStackStampInformation to $($Env:ProgramData)" -ForegroundColor Green $JSONFile | ConvertTo-Json | Out-File -FilePath "$($Env:ProgramData)\AzureStackStampInformation.json" -Force [string]$FoundDomainFQDN = $JSONFile.DomainFQDN [array]$ERCSIPS = $JSONFile.EmergencyConsoleIPAddresses $StampTimeZone = $JSONFile.Timezone $selERCSIP = $ERCSIPS | Out-GridView -Title "Please Select Emergency Console IPAddress" -PassThru $IP = $selERCSIP } } "No" {Write-Host "`n `t[INFO] No AzureStackStampInformation.json file loaded" -ForegroundColor White} } } #ERCs Prefix check if(!($IP)) { function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText) { Add-Type -AssemblyName Microsoft.VisualBasic return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText) } Write-Host "`n`t[Prompt] for prefix name" -ForegroundColor White $AzSPrefix = Read-InputBoxDialog -Message "Please enter Azure Stack install prefix:" -WindowTitle "Azure Stack prefix" -DefaultText "AzS" If($AzSPrefix) { [Array]$GuessERCSName += $AzSPrefix + "-ERCS01" [Array]$GuessERCSName += $AzSPrefix + "-ERCS02" [Array]$GuessERCSName += $AzSPrefix + "-ERCS03" } ForEach ($GuessERCName in $GuessERCSName) { $global:progresspreference ="SilentlyContinue" $GuessName = Test-NetConnection -port 5985 -ComputerName $GuessERCName -WarningAction SilentlyContinue If ($GuessName.TcpTestSucceeded -eq "True") { [Array]$ListeningNames += $GuessName.RemoteAddress.IPAddressToString } } $global:progresspreference ="Continue" $selName = $ListeningNames |Out-GridView -PassThru -Title "Select Emergency Recovery Console Session" $IP = $selName } #InStamp Check if($InStamp -eq "Yes"){$CheckADSK = 1} if (!($InStamp)) { #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $OnStampForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.Label]$OnStampLabel = $null [System.Windows.Forms.Button]$OnStampYes = $null [System.Windows.Forms.Button]$OnStampNo = $null [System.Windows.Forms.Button]$button1 = $null $OnStampLabel = New-Object -TypeName System.Windows.Forms.Label $OnStampYes = New-Object -TypeName System.Windows.Forms.Button $OnStampNo = New-Object -TypeName System.Windows.Forms.Button $OnStampForm.SuspendLayout() # #OnStampLabel # $OnStampLabel.AutoSize = $true $OnStampLabel.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,22) $OnStampLabel.Name = 'OnStampLabel' $OnStampLabel.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(270,13) $OnStampLabel.TabIndex = 0 $OnStampLabel.Text = 'Are you running script from the ASDK or DVM machine?' $OnStampLabel.TextAlign = [System.Drawing.ContentAlignment]::TopCenter $OnStampLabel.add_Click($OnStampLabel_Click) # #OnStampYes # $OnStampYes.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(62,55) $OnStampYes.Name = 'OnStampYes' $OnStampYes.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $OnStampYes.TabIndex = 1 $OnStampYes.Text = 'Yes' $OnStampYes.UseVisualStyleBackColor = $true $OnStampYes.DialogResult = [System.Windows.Forms.DialogResult]::Yes # #OnStampNo # $OnStampNo.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(143,55) $OnStampNo.Name = 'OnStampNo' $OnStampNo.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $OnStampNo.TabIndex = 2 $OnStampNo.Text = 'No' $OnStampNo.UseVisualStyleBackColor = $true $OnStampNo.DialogResult = [System.Windows.Forms.DialogResult]::No # #OnStampForm # $OnStampForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(298,99) $OnStampForm.Controls.Add($OnStampNo) $OnStampForm.Controls.Add($OnStampYes) $OnStampForm.Controls.Add($OnStampLabel) $OnStampForm.Name = 'OnStampForm' $OnStampForm.Text = 'On Stamp Prompt' $OnStampForm.add_Load($MainForm_Load) $OnStampForm.ResumeLayout($false) $OnStampForm.AcceptButton = $OnStampNo $OnStampForm.PerformLayout() Add-Member -InputObject $OnStampForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $OnStampForm -Name OnStampLabel -Value $OnStampLabel -MemberType NoteProperty Add-Member -InputObject $OnStampForm -Name OnStampYes -Value $OnStampYes -MemberType NoteProperty Add-Member -InputObject $OnStampForm -Name OnStampNo -Value $OnStampNo -MemberType NoteProperty Add-Member -InputObject $OnStampForm -Name button1 -Value $button1 -MemberType NoteProperty $OnStampForm.Topmost = $True $OnStampForm.StartPosition = "CenterScreen" $OnStampForm.MaximizeBox = $false $OnStampForm.FormBorderStyle = 'Fixed3D' $ASDKQuestion = $OnStampForm.ShowDialog() #endregion .NET if ($ASDKQuestion -eq [System.Windows.Forms.DialogResult]::yes) { Write-Host "`n `t[INFO] Using Azure Stack Development Kit or DVM" -ForegroundColor Green $CheckADSK = 1 } } #Get Stamp Timezone If (!($StampTimeZone)) { $SelCurrentTimeZone = [system.timezoneinfo]::GetSystemTimeZones() | Out-GridView -PassThru -Title "Select AzureStack Stamp installed timezone" [String]$StampTimeZone = $SelCurrentTimeZone.Id If ($StampTimeZone -eq $null) { Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } #AD Query if(!($IP)) { #AD Query if(!($IP)) { $moduleName = $null $moduleName = "ActiveDirectory" #inform the user of that we are doing Write-Host "`n`t[INFO] Checking for AD powershell module" -ForegroundColor Green try { if (load_module $moduleName) { Write-Host "`n`t[Info] Loaded $($moduleName)" -ForegroundColor Green } else { Write-Host "`n`t`t[Warning] Failed to load $($moduleName)" -ForegroundColor Yellow Write-Host "`n`t[Info] Installing module $($moduleName)" -ForegroundColor Gray Install-WindowsFeature -Name RSAT-AD-PowerShell Try { if (load_module $moduleName) { Write-Host "`n`t`t[Info] Loaded $($moduleName)" -ForegroundColor White } } catch { Write-Host "`n`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } } catch { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } #go get the computers and find ECR machines $ERCSNames = $null $ERCIPInfo = $null $selERC = $null Write-Host "`n`t[Info] Querying for Emergency Recovery Console Session with AD" -ForegroundColor Green [Array] $ERCSNames = Get-ADComputer -Filter 'ObjectClass -eq "Computer"' | where {$_.name -like "*-Ercs*"} | Select -Expand Name foreach ($name in $ERCSNames) { $ERCName = Resolve-DnsName -name $name | select Name, Ipaddress [array]$ERCIPInfo += $ERCName } #pick Emergency Recovery Console Session $selERC = $ERCIPInfo | Out-GridView -PassThru -Title "Select Emergency Recovery Console Session" $IP = $selERC.ipaddress } else { Write-Host "`n`t[INFO] Unable to find ip address of Emergency Recovery Console Session via AD" -ForegroundColor DarkYellow } } #DNS QUERY if(!($IP)) { #DNS QUERY A records if(!($IP)) { try { $moduleName = $null $moduleName = "DnsServer" #inform the user of that we are doing Write-Host "`n`t[INFO] Checking for DNS powershell module" -ForegroundColor White if (load_module $moduleName) { Write-Host "`n`t[INFO] Loaded $($moduleName)" -ForegroundColor Green } else { Write-Host "`n`t`t[Warning] Failed to load $($moduleName)" -ForegroundColor Yellow Write-Host "`n`t[INFO] Installing module $($moduleName)" -ForegroundColor Gray Install-WindowsFeature -Name RSAT-DNS-Server Try { if (load_module $moduleName) { Write-Host "`n`t`t[INFO] Loaded $($moduleName)" -ForegroundColor White } } catch { Write-Host "`n`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } } catch { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } Write-Host "`n`t[INFO] Looking for Emergency Recovery Console Session via DNS" $DnsServers = $null $server = $null $Zones = $null $Zone = $null $ErcServers = $null $ERCSSERVER = $null Write-Host "`n`t[INFO] Querying for Emergency Recovery Console Session A records" -ForegroundColor White [array]$DnsServers = Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object –ExpandProperty ServerAddresses $DnsServers = $DnsServers | select -uniq ForEach ($server in $DnsServers) { $Zones = @(Get-DnsServerZone -ComputerName $server) ForEach ($Zone in $Zones) { [array]$ERCSSERVER= Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ComputerName $server -RRType "A" | select HostName,RecordType,Timestamp,TimeToLive,@{Name='RecordData';Expression={$_.RecordData.IPv4Address.ToString()}} | where {$_.Hostname -like "*-ERCS*"} [array]$ErcServers += $ERCSSERVER } } $nodupERCs = $ErcServers | Sort-Object -Property RecordData -Unique $SelErcServers = $nodupERCs | Select-Object HostName, RecordData | Out-GridView -PassThru -Title "Select Emergency Recovery Console Session" $IP = $SelErcServers.RecordData } # look for forwarders then change out the IP addresses to likly ERCS ip addresses then test connection if (!($IP)) { Write-host "`n`t[INFO] Unable to locate via DNS A record search." -ForegroundColor White Write-host "`n`t[INFO] Searching for AzureStack.local zones" -ForegroundColor White [array]$DNSServers=Get-DNSClientServerAddress -AddressFamily IPv4 | ?{$_.ServerAddresses -ne $null} | Select ServerAddresses -Unique foreach ($DNSServer in $DNSServers) { [array]$AzSDNSSvrs+= get-dnsserverzone -computername $($DNSServer.ServerAddresses) | ?{$_.ZoneName -like "*azurestack.local"} } If ($AzSDNSSvrs.ZoneType -contains "Forwarder") { foreach($AzSDNSSvr in $AzSDNSSvrs.MasterServers) { [array]$IPArrays+=(($AzSDNSSvr.IPAddressToString -split "\.")[0..2]) -join "." } $IPArrays = $IPArrays| select -Unique foreach($iparray in $IPArrays) { [Array]$GuessERCS += $IPArray + "." + "225" [Array]$GuessERCS += $IPArray + "." + "226" [Array]$GuessERCS += $IPArray + "." + "227" } ForEach ($ERCTest in $GuessERCS) { $global:progresspreference ="SilentlyContinue" $DNSGuessName = Test-NetConnection -port 5985 -ComputerName $ERCTest If ($GuessName.TcpTestSucceeded -eq "True") { [Array]$DNSListeningNames += $DNSGuessName.RemoteAddress.IPAddressToString } } $global:progresspreference ="Continue" $DNSselName = $DNSListeningNames |Out-GridView -PassThru -Title "Select Emergency Recovery Console Session" $IP = $DNSselName } else { Write-Host "`n`t[INFO] Unable to find ip address of Emergency Recovery Console Session via DNS" -ForegroundColor White } } } #BestguessIP if(!($IP)) { function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText) { Add-Type -AssemblyName Microsoft.VisualBasic return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText) } Write-Host "`n`t[Prompt] for Azure Stack Portal" $AzSPortal = Read-InputBoxDialog -Message "Please enter Azure Stack Portal:" -WindowTitle "Azure Stack Portal" -DefaultText "http://portal.local.azurestack.external" $Tenant = ($AzSPortal -split "//")[-1] $portal= Test-NetConnection -Port 443 -ComputerName $Tenant If ($portal.TcpTestSucceeded -eq "True") { $octet = $portal.Remoteaddress.IPAddressToString $occarr = $octet.split(".") [Array]$GuessERCS += $occarr[0] + "." + $occarr[1] + "." + $occarr[2] + "." + "225" [Array]$GuessERCS += $occarr[0] + "." + $occarr[1] + "." + $occarr[2] + "." + "226" [Array]$GuessERCS += $occarr[0] + "." + $occarr[1] + "." + $occarr[2] + "." + "227" [Array]$GuessERCS += $occarr[0] + "." + $occarr[1] + "." + "200" + "." + "225" #for devkit } ForEach ($GuessERC in $GuessERCS) { $global:progresspreference ="SilentlyContinue" $GuessIP = Test-NetConnection -port 5985 -ComputerName $GuessERC If ($GuessIP.TcpTestSucceeded -eq "True") { [Array]$Listeningips += $GuessIP.RemoteAddress.IPAddressToString } } $global:progresspreference ="Continue" $selIP = $Listeningips |Out-GridView -PassThru -Title "Select Emergency Recovery Console Session" $IP = $selIP } #Manual Entry if(!($IP)) { #Manual Entry if(!($IP)) { Write-Host "`n`t[PROMPT] Enter IP Address of Emergency Recovery Console Session" -ForegroundColor White [string]$IP = Read-Host "`n`tInput ERCS ip Address" } else { Write-Host "`n`t[INFO] Unable to find ip address of Emergency Recovery Console Session via manual entry" -ForegroundColor DarkYellow } } #Do Work if($IP) { function Convert-AZSServerTime ( [parameter( Mandatory=$true)] [ValidateNotNullOrEmpty()] [datetime]$DateTime ) { $strCurrentTimeZone = $StampTimeZone $ToTimeZoneObj = [system.timezoneinfo]::GetSystemTimeZones() | Where-Object {$_.id -eq $strCurrentTimeZone} $TargetZoneTime = [system.timezoneinfo]::ConvertTime($datetime, $ToTimeZoneObj) $TargetZoneTime } Try { Write-Host "`n `t[INFO] Using $($IP)" -ForegroundColor Green #Add this machine to trusted Hosts if ($ERCSIPS) { $ERCS = $ERCSIPS -join "," Set-Item WSMan:\localhost\Client\TrustedHosts -Value "$($ERCS)" -Force } else { Set-Item WSMan:\localhost\Client\TrustedHosts -Value "$($IP)" -Force } #gethostip $global:progresspreference ="SilentlyContinue" Write-Host "`n `t[INFO] Testing connectivity to $($IP)" -ForegroundColor Green $testconnect = Test-NetConnection -port 5985 -ComputerName $IP If ($testconnect.TcpTestSucceeded -eq "True") { Write-Host "`tSuccess" If ($IncompleteDeployment -ne "Yes") { $remoteip = $testconnect.RemoteAddress.IPAddressToString $share = $testconnect.SourceAddress.IPAddress $myname = whoami $date = Get-Date -format MM-dd-hhmm $foldername = "-AzureStackLogs" $sharename = $date + $foldername If (!(Test-Path "$($Env:SystemDrive)\$($sharename)")) {$folder = New-Item -Path "$($Env:SystemDrive)\$($sharename)" -ItemType directory} $foldershare= New-SMBShare –Name $sharename –Path "$($Env:SystemDrive)\$($sharename)" -FullAccess $myname If($foldershare){[string]$ShareINFO = "\\$($share)\$sharename"} } } Else { $global:progresspreference ="Continue" Write-Host "`n `t[ERROR] Cannot connect to Emergency Recovery Console Session to $($remoteip) from $($share)" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } $global:progresspreference ="Continue" #username to connect to AzureStack form if($AzSCredentials) {$mySecureCredentials = $AzSCredentials} if(!($AzSCredentials)) { if(!($FoundDomainFQDN)) { #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $DomainForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.Button]$DomainOK = $null [System.Windows.Forms.TextBox]$Domaintextbox = $null [System.Windows.Forms.Label]$label1 = $null [System.Windows.Forms.Button]$button1 = $null $Domaintextbox = New-Object -TypeName System.Windows.Forms.TextBox $DomainOK = New-Object -TypeName System.Windows.Forms.Button $label1 = New-Object -TypeName System.Windows.Forms.Label $DomainForm.SuspendLayout() # #Domaintextbox # $Domaintextbox.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,45) $Domaintextbox.Name = 'Domaintextbox' $Domaintextbox.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(233,20) $Domaintextbox.TabIndex = 0 $Domaintextbox.Text = 'AzureStack' # #DomainOK # $DomainOK.DialogResult = [System.Windows.Forms.DialogResult]::OK $DomainOK.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(251,43) $DomainOK.Name = 'DomainOK' $DomainOK.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $DomainOK.TabIndex = 1 $DomainOK.Text = 'OK' $DomainOK.UseVisualStyleBackColor = $true # #label1 # $label1.AutoSize = $true $label1.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,19) $label1.Name = 'label1' $label1.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(233,13) $label1.TabIndex = 2 $label1.Text = 'What is the AzureStack Internal Domain Name?' $label1.add_Click($label1_Click) # #DomainForm # $DomainForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(331,74) $DomainForm.Controls.Add($label1) $DomainForm.Controls.Add($DomainOK) $DomainForm.Controls.Add($Domaintextbox) $DomainForm.Name = 'DomainForm' $DomainForm.Text = 'AzureStack Domain Prompt' $DomainForm.add_Load($DomainForm_Load) $DomainForm.ResumeLayout($false) $DomainForm.PerformLayout() Add-Member -InputObject $DomainForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $DomainForm -Name DomainOK -Value $DomainOK -MemberType NoteProperty Add-Member -InputObject $DomainForm -Name Domaintextbox -Value $Domaintextbox -MemberType NoteProperty Add-Member -InputObject $DomainForm -Name label1 -Value $label1 -MemberType NoteProperty Add-Member -InputObject $DomainForm -Name button1 -Value $button1 -MemberType NoteProperty $DomainForm.Topmost = $True $DomainForm.StartPosition = "CenterScreen" $DomainForm.MaximizeBox = $false $DomainForm.FormBorderStyle = 'Fixed3D' [System.Object]$userinputdomain = $null $userinputdomain = $DomainForm.ShowDialog() #endregion .NET if ($userinputdomain -eq [System.Windows.Forms.DialogResult]::OK) { $FoundDomainFQDN = $Domaintextbox.Text } } if($FoundDomainFQDN) { $UserFoundDomainFQDN = ($FoundDomainFQDN + "\") } Write-Host "`n`t[PROMPT] Select a username for connecting to AzureStack PEP" -ForegroundColor Green #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $UserForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.ComboBox]$comboBox1 = $null [System.Windows.Forms.Button]$ok = $null [System.Windows.Forms.Button]$button1 = $null $comboBox1 = New-Object -TypeName System.Windows.Forms.ComboBox $ok = New-Object -TypeName System.Windows.Forms.Button $UserForm.SuspendLayout() # #comboBox1 # $comboBox1.FormattingEnabled = $true $comboBox1.Items.AddRange("$($UserFoundDomainFQDN)CloudAdmin") if($CheckADSK -eq 1) { $comboBox1.Items.AddRange("$($UserFoundDomainFQDN)AzureStackAdmin") } $comboBox1.Items.AddRange("User Input") $comboBox1.SelectedIndex = 0 $comboBox1.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,29) $comboBox1.Name = 'comboBox1' $comboBox1.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(226,21) $comboBox1.TabIndex = 0 # #ok # $ok.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(255,29) $ok.Name = 'ok' $ok.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(75,23) $ok.TabIndex = 1 $ok.Text = 'Ok' $ok.UseVisualStyleBackColor = $true $ok.DialogResult = [System.Windows.Forms.DialogResult]::OK # #UserForm # $UserForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(344,74) $UserForm.Controls.Add($ok) $UserForm.Controls.Add($comboBox1) $UserForm.Name = 'UserForm' $UserForm.Text = 'Username for AzureStack' $UserForm.add_Load($MainForm_Load) $UserForm.ResumeLayout($false) Add-Member -InputObject $UserForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $UserForm -Name comboBox1 -Value $comboBox1 -MemberType NoteProperty Add-Member -InputObject $UserForm -Name ok -Value $ok -MemberType NoteProperty Add-Member -InputObject $UserForm -Name button1 -Value $button1 -MemberType NoteProperty $UserForm.Topmost = $True $UserForm.StartPosition = "CenterScreen" $UserForm.MaximizeBox = $false $UserForm.FormBorderStyle = 'Fixed3D' $AzsUser = $UserForm.ShowDialog() #endregion .NET if ($AzsUser -eq [System.Windows.Forms.DialogResult]::OK) { Write-Host "`tSelected $($comboBox1.SelectedItem)" -ForegroundColor White If($comboBox1.SelectedItem -eq "User Input") {$selAzSUser = $null}else{[string]$selAzSUser = $comboBox1.SelectedItem} } #Username and password colection Write-Host "`n`t[PROMPT] Enter credential to connect to AzureStack PEP" -ForegroundColor Green $mySecureCredentials = Get-Credential -Message "Azure Stack credentials" -UserName $selAzSUser } #ShareUserINFO if(!($shareCred)) { $name = whoami $localComputer = (gwmi Win32_ComputerSystem).Name $shareCred = Get-Credential -UserName $name -Message "Local share credentials" $localusername = $shareCred.username $localpassword = $shareCred.GetNetworkCredential().password $LocalUsers = ("$localComputer"+"$localusername") $localCurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName $localdomain = New-Object System.DirectoryServices.DirectoryEntry($localCurrentDomain,$localusername,$localpassword) $localmachine = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine) $localval = $localmachine.ValidateCredentials($localusername, $localpassword) if (($localdomain.name -eq $null) -and ($localval -eq $false)) { Write-Host "`n`t[ERROR] Authentication failed for $($localusername)" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } else { Write-Host "`n `t[INFO] Successfully authenticated as $($localusername)" -ForegroundColor Green } } #form for start question if (!($FromDate)) { #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $TimeForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.DateTimePicker]$StartTimePicker = $null [System.Windows.Forms.Label]$Start = $null [System.Windows.Forms.Label]$24Hour = $null [System.Windows.Forms.Label]$Occur = $null [System.Windows.Forms.Button]$TimeOk = $null [System.Windows.Forms.Button]$timecancel = $null [System.Windows.Forms.Button]$button1 = $null $StartTimePicker = New-Object -TypeName System.Windows.Forms.DateTimePicker $Start = New-Object -TypeName System.Windows.Forms.Label $24Hour = New-Object -TypeName System.Windows.Forms.Label $Occur = New-Object -TypeName System.Windows.Forms.Label $TimeOk = New-Object -TypeName System.Windows.Forms.Button $timecancel = New-Object -TypeName System.Windows.Forms.Button $TimeForm.SuspendLayout() # #StartTimePicker # $StartTimePicker.CustomFormat = 'MMMMdd, yyyy | HH:mm' $StartTimePicker.Format = [System.Windows.Forms.DateTimePickerFormat]::Custom $StartTimePicker.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(76,58) $StartTimePicker.Name = 'StartTimePicker' $StartTimePicker.ShowUpDown = $true $StartTimePicker.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(165,20) $StartTimePicker.TabIndex = 0 $StartTimePicker.Value = (get-date).AddHours(-4) $StartTimePicker.MaxDate = (get-date).AddHours(-1) # #Start # $Start.AutoSize = $true $Start.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,62) $Start.Name = 'Start' $Start.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(58,13) $Start.TabIndex = 2 $Start.Text = 'Start Time:' # #24Hour # $24Hour.AutoSize = $true $24Hour.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(103,95) $24Hour.Name = '24Hour' $24Hour.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(138,13) $24Hour.TabIndex = 4 $24Hour.Text = '** All times in 24 hour format' # #Occur # $Occur.AutoSize = $true $Occur.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,25) $Occur.Name = 'Occur' $Occur.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(127,13) $Occur.TabIndex = 5 $Occur.Text = 'When did the issue start?' # #TimeOk # $TimeOk.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(162,131) $TimeOk.Name = 'TimeOk' $TimeOk.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(96,28) $TimeOk.TabIndex = 6 $TimeOk.Text = 'Ok' $TimeOk.UseVisualStyleBackColor = $true $TimeOk.DialogResult = [System.Windows.Forms.DialogResult]::OK # #timecancel # $timecancel.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(15,131) $timecancel.Name = 'timecancel' $timecancel.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(99,28) $timecancel.TabIndex = 7 $timecancel.Text = 'Cancel' $timecancel.UseVisualStyleBackColor = $true $timecancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel # #TimeForm # $TimeForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(270,180) $TimeForm.Controls.Add($timecancel) $TimeForm.Controls.Add($TimeOk) $TimeForm.Controls.Add($Occur) $TimeForm.Controls.Add($24Hour) $TimeForm.Controls.Add($Start) $TimeForm.Controls.Add($StartTimePicker) $TimeForm.Name = 'TimeForm' $TimeForm.Text = 'Issue occurrence' $TimeForm.ResumeLayout($false) $TimeForm.PerformLayout() Add-Member -InputObject $TimeForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name StartTimePicker -Value $StartTimePicker -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name Start -Value $Start -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name 24Hour -Value $24Hour -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name Occur -Value $Occur -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name TimeOk -Value $TimeOk -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name timecancel -Value $timecancel -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name button1 -Value $button1 -MemberType NoteProperty $TimeForm.Topmost = $True $TimeForm.StartPosition = "CenterScreen" $TimeForm.MaximizeBox = $false $TimeForm.FormBorderStyle = 'Fixed3D' $timeresult = $TimeForm.ShowDialog() #endregion .NET if ($timeresult -eq [System.Windows.Forms.DialogResult]::Cancel){$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");exit} if ($timeresult -eq [System.Windows.Forms.DialogResult]::OK) { [DateTime]$FromDate = $StartTimePicker.Value if($FromDate -lt (get-date)) { Write-Host "`n`t[INFO] When should tracing Start?" -ForegroundColor Green Write-Host "`tSelected $($FromDate)" $AzSFromDate = Convert-AZSServerTime -DateTime $FromDate Write-Host "`tStamp Time $($AzSFromDate)" -ForegroundColor Gray } else { Write-Host "`n`t[ERROR] Date entry incorrect" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } } if (!($ToDate)) { #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $TimeForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.Label]$24Hour = $null [System.Windows.Forms.Label]$Occur = $null [System.Windows.Forms.Button]$TimeOk = $null [System.Windows.Forms.Button]$timecancel = $null [System.Windows.Forms.DateTimePicker]$EndTimePicker = $null [System.Windows.Forms.Label]$End = $null [System.Windows.Forms.Button]$button1 = $null $24Hour = New-Object -TypeName System.Windows.Forms.Label $Occur = New-Object -TypeName System.Windows.Forms.Label $TimeOk = New-Object -TypeName System.Windows.Forms.Button $timecancel = New-Object -TypeName System.Windows.Forms.Button $EndTimePicker = New-Object -TypeName System.Windows.Forms.DateTimePicker $End = New-Object -TypeName System.Windows.Forms.Label $TimeForm.SuspendLayout() # #24Hour # $24Hour.AutoSize = $true $24Hour.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(103,102) $24Hour.Name = '24Hour' $24Hour.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(138,13) $24Hour.TabIndex = 4 $24Hour.Text = '** All times in 24 hour format' # #Occur # $Occur.AutoSize = $true $Occur.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,25) $Occur.Name = 'Occur' $Occur.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(125,13) $Occur.TabIndex = 5 $Occur.Text = 'When did the issue end?' # #TimeOk # $TimeOk.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(162,138) $TimeOk.Name = 'TimeOk' $TimeOk.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(96,23) $TimeOk.TabIndex = 6 $TimeOk.Text = 'Ok' $TimeOk.UseVisualStyleBackColor = $true $TimeOk.DialogResult = [System.Windows.Forms.DialogResult]::OK # #timecancel # $timecancel.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(15,138) $timecancel.Name = 'timecancel' $timecancel.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(99,23) $timecancel.TabIndex = 7 $timecancel.Text = 'Cancel' $timecancel.UseVisualStyleBackColor = $true $timecancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel # #EndTimePicker # $EndTimePicker.CustomFormat = 'MMMMdd, yyyy | HH:mm' $EndTimePicker.Format = [System.Windows.Forms.DateTimePickerFormat]::Custom $EndTimePicker.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(82,59) $EndTimePicker.Name = 'EndTimePicker' $EndTimePicker.ShowUpDown = $true $EndTimePicker.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(165,20) $EndTimePicker.TabIndex = 1 $EndTimePicker.Value = (get-date) $EndTimePicker.MaxDate = (get-date) $EndTimePicker.MinDate = $StartTimePicker.Value.AddHours(1) # #End # $End.AutoSize = $true $End.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(18,63) $End.Name = 'End' $End.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(55,13) $End.TabIndex = 3 $End.Text = 'End Time:' # #TimeForm # $TimeForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(270,181) $TimeForm.Controls.Add($timecancel) $TimeForm.Controls.Add($TimeOk) $TimeForm.Controls.Add($Occur) $TimeForm.Controls.Add($24Hour) $TimeForm.Controls.Add($End) $TimeForm.Controls.Add($EndTimePicker) $TimeForm.Name = 'TimeForm' $TimeForm.Text = 'Issue occurrence' $TimeForm.ResumeLayout($false) $TimeForm.PerformLayout() Add-Member -InputObject $TimeForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name 24Hour -Value $24Hour -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name Occur -Value $Occur -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name TimeOk -Value $TimeOk -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name timecancel -Value $timecancel -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name EndTimePicker -Value $EndTimePicker -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name End -Value $End -MemberType NoteProperty Add-Member -InputObject $TimeForm -Name button1 -Value $button1 -MemberType NoteProperty $TimeForm.Topmost = $True $TimeForm.StartPosition = "CenterScreen" $TimeForm.MaximizeBox = $false $TimeForm.FormBorderStyle = 'Fixed3D' $timeresult = $TimeForm.ShowDialog() #endregion .NET if ($timeresult -eq [System.Windows.Forms.DialogResult]::Cancel){$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");exit} if ($timeresult -eq [System.Windows.Forms.DialogResult]::OK) { [DateTime]$ToDate = $EndTimePicker.Value if($ToDate -gt ($FromDate)) { Write-Host "`n`t[INFO] When should tracing Stop?" -ForegroundColor Green Write-Host "`tSelected $($ToDate)" $AzSToDate = Convert-AZSServerTime -DateTime $ToDate Write-Host "`tStamp Time $($AzSToDate)" -ForegroundColor Gray } else { Write-Host "`n`t[ERROR] Date entry incorrect" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } } #Set the time out here to account for timezones changes Convert-AZSServerTime will make if($AzSFromDate){$FromDate = $AzSFromDate} if($AzSToDate){$ToDate = $AzSToDate} # filter by role form If(!($FilterByRole)) { Write-Host "`n`t[PROMPT] What should be collected?" -ForegroundColor Green #region .NET [void][System.Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') [void][System.Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') $MainForm = New-Object -TypeName System.Windows.Forms.Form [System.Windows.Forms.CheckedListBox]$checkedListBox1 = $null [System.Windows.Forms.Button]$buttonselect = $null [System.Windows.Forms.Button]$buttondefault = $null [System.Windows.Forms.Button]$button1 = $null [System.Windows.Forms.Label]$label1 = $null [System.Windows.Forms.Label]$label2 = $null [System.Object]$selLogCollection = $null $checkedListBox1 = New-Object -TypeName System.Windows.Forms.CheckedListBox $buttonselect = New-Object -TypeName System.Windows.Forms.Button $buttondefault = New-Object -TypeName System.Windows.Forms.Button $label1 = New-Object -TypeName System.Windows.Forms.Label $label2 = New-Object -TypeName System.Windows.Forms.Label $MainForm.SuspendLayout() # #checkedListBox1 # $checkedListBox1.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,12) $checkedListBox1.Items.AddRange("ACS") $checkedListBox1.Items.AddRange("ACSBlob") $checkedListBox1.Items.AddRange("ACSFabric") $checkedListBox1.Items.AddRange("ACSFrontEnd") $checkedListBox1.Items.AddRange("ACSMetrics") $checkedListBox1.Items.AddRange("ACSMigrationService") $checkedListBox1.Items.AddRange("ACSMonitoringService") $checkedListBox1.Items.AddRange("ACSSettingsService") $checkedListBox1.Items.AddRange("ACSTableMaster") $checkedListBox1.Items.AddRange("ACSTableServer") $checkedListBox1.Items.AddRange("ACSWac") $checkedListBox1.Items.AddRange("ADFS") $checkedListBox1.Items.AddRange("ASAppGateway") $checkedListBox1.Items.AddRange("AzureBridge") $checkedListBox1.Items.AddRange("AzurePackConnector") $checkedListBox1.Items.AddRange("AzureStackBitlocker **") $checkedListBox1.Items.AddRange("BareMetal") $checkedListBox1.Items.AddRange("BGP *") $checkedListBox1.Items.AddRange("BRP") $checkedListBox1.Items.AddRange("CA") $checkedListBox1.Items.AddRange("Cloud") $checkedListBox1.Items.AddRange("Compute **") $checkedListBox1.Items.AddRange("CPI") $checkedListBox1.Items.AddRange("CRP") $checkedListBox1.Items.AddRange("DatacenterIntegration") $checkedListBox1.Items.AddRange("DeploymentMachine **") $checkedListBox1.Items.AddRange("Domain") $checkedListBox1.Items.AddRange("ECE") $checkedListBox1.Items.AddRange("ExternalDNS") $checkedListBox1.Items.AddRange("Fabric") $checkedListBox1.Items.AddRange("FabricRing") $checkedListBox1.Items.AddRange("FabricRingServices") $checkedListBox1.Items.AddRange("FRP") $checkedListBox1.Items.AddRange("Gallery") $checkedListBox1.Items.AddRange("Gateway") $checkedListBox1.Items.AddRange("HealthMonitoring") $checkedListBox1.Items.AddRange("HRP") $checkedListBox1.Items.AddRange("IBC") $checkedListBox1.Items.AddRange("IdentityProvider") $checkedListBox1.Items.AddRange("iDns") $checkedListBox1.Items.AddRange("InfraServiceController") $checkedListBox1.Items.AddRange("Infrastructure") $checkedListBox1.Items.AddRange("KeyVaultAdminResourceProvider") $checkedListBox1.Items.AddRange("KeyVaultControlPlane") $checkedListBox1.Items.AddRange("KeyVaultDataPlane") $checkedListBox1.Items.AddRange("KeyVaultInternalControlPlane") $checkedListBox1.Items.AddRange("KeyVaultInternalDataPlane") $checkedListBox1.Items.AddRange("KeyVaultNamingService") $checkedListBox1.Items.AddRange("MonitoringAgent") $checkedListBox1.Items.AddRange("NC") $checkedListBox1.Items.AddRange("NonPrivilegedAppGateway") $checkedListBox1.Items.AddRange("NRP") $checkedListBox1.Items.AddRange("OEM **") $checkedListBox1.Items.AddRange("PXE **") $checkedListBox1.Items.AddRange("POC *") $checkedListBox1.Items.AddRange("SeedRing") $checkedListBox1.Items.AddRange("SeedRingServices") $checkedListBox1.Items.AddRange("SLB") $checkedListBox1.Items.AddRange("SlbVips") $checkedListBox1.Items.AddRange("SQL") $checkedListBox1.Items.AddRange("SRP") $checkedListBox1.Items.AddRange("Storage") $checkedListBox1.Items.AddRange("StorageAccounts") $checkedListBox1.Items.AddRange("StorageController") $checkedListBox1.Items.AddRange("Tenant") $checkedListBox1.Items.AddRange("TraceCollector") $checkedListBox1.Items.AddRange("URP") $checkedListBox1.Items.AddRange("UsageBridge") $checkedListBox1.Items.AddRange("VirtualMachines") $checkedListBox1.Items.AddRange("WAS") $checkedListBox1.Items.AddRange("WASBootstrap") $checkedListBox1.Items.AddRange("WASPUBLIC") $checkedListBox1.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(260,214) $checkedListBox1.TabIndex = 0 # #buttonselect # $buttonselect.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(12,262) $buttonselect.Name = 'buttonselect' $buttonselect.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(121,23) $buttonselect.TabIndex = 1 $buttonselect.Text = 'Selected Item(s)' $buttonselect.UseVisualStyleBackColor = $true $buttonselect.DialogResult = [System.Windows.Forms.DialogResult]::OK # #buttondefault # $buttondefault.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(139,262) $buttondefault.Name = 'buttondefault' $buttondefault.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(133,23) $buttondefault.TabIndex = 2 $buttondefault.Text = 'Default Logs' $buttondefault.UseVisualStyleBackColor = $true $buttondefault.DialogResult = [System.Windows.Forms.DialogResult]::Ignore # #label1 # $label1.AutoSize = $true $label1.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(9,229) $label1.Name = 'label1' $label1.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(67,13) $label1.TabIndex = 3 $label1.Text = '* ASDK Only' $label1.add_Click($label1_Click) # #label2 # $label2.AutoSize = $true $label2.Location = New-Object -TypeName System.Drawing.Point -ArgumentList @(9,242) $label2.Name = 'label2' $label2.Size = New-Object -TypeName System.Drawing.Size -ArgumentList @(88,13) $label2.TabIndex = 4 $label2.Text = '** MutiNode Only' # #MainForm # $MainForm.AcceptButton = $buttondefault $MainForm.ClientSize = New-Object -TypeName System.Drawing.Size -ArgumentList @(284,289) $MainForm.Controls.Add($label2) $MainForm.Controls.Add($label1) $MainForm.Controls.Add($buttondefault) $MainForm.Controls.Add($buttonselect) $MainForm.Controls.Add($checkedListBox1) $MainForm.Name = 'MainForm' $MainForm.Text = 'Log collection' $MainForm.ResumeLayout($false) $MainForm.AcceptButton = $buttondefault $MainForm.PerformLayout() Add-Member -InputObject $MainForm -Name base -Value $base -MemberType NoteProperty Add-Member -InputObject $MainForm -Name checkedListBox1 -Value $checkedListBox1 -MemberType NoteProperty Add-Member -InputObject $MainForm -Name buttonselect -Value $buttonselect -MemberType NoteProperty Add-Member -InputObject $MainForm -Name buttondefault -Value $buttondefault -MemberType NoteProperty Add-Member -InputObject $MainForm -Name button1 -Value $button1 -MemberType NoteProperty Add-Member -InputObject $MainForm -Name label1 -Value $label1 -MemberType NoteProperty Add-Member -InputObject $MainForm -Name label2 -Value $label2 -MemberType NoteProperty Add-Member -InputObject $MainForm -Name selLogCollection -Value $selLogCollection -MemberType NoteProperty $MainForm.Topmost = $True $MainForm.StartPosition = "CenterScreen" $MainForm.MaximizeBox = $false $MainForm.FormBorderStyle = 'Fixed3D' $LogCollection = $MainForm.ShowDialog() #region .NET if ($LogCollection -eq [System.Windows.Forms.DialogResult]::OK) { [string[]]$FilterByRole = ((($checkedListBox1.CheckedItems -replace "[*]").Trim()) | Select-Object -Unique) Write-Host "`tSelected $($FilterByRole) for log collection" -ForegroundColor White } if ($LogCollection -eq [System.Windows.Forms.DialogResult]::Ignore) { Write-Host "`tSelected default role log collection" -ForegroundColor White $defaultLogCollection = $true } $maxtimespan = new-timespan -Days 0 -Hours 7 -Minutes 59 -Seconds 0 if (($defaultLogCollection -eq $true) -and (($ToDate - $FromDate) -ge $maxtimespan)) { If ($IncompleteDeployment -ne "Yes"){Write-Host "`t[WARNING] Log truncation probable" -ForegroundColor Yellow} } } If($IncompleteDeployment -eq "Yes") { $checkdiag = test-path -Path "$($env:SystemDrive)\CloudDeployment\AzureStackDiagnostics\Microsoft.AzureStack.Diagnostics.DataCollection\Microsoft.AzureStack.Diagnostics.DataCollection.psm1" if($checkdiag -eq $true) { Import-Module "$($env:SystemDrive)\CloudDeployment\AzureStackDiagnostics\Microsoft.AzureStack.Diagnostics.DataCollection\Microsoft.AzureStack.Diagnostics.DataCollection.psm1" -WarningAction SilentlyContinue -ErrorAction SilentlyContinue $AzSDig = Get-Module -Name Microsoft.AzureStack.Diagnostics.DataCollection } if ($AzSDig.Name -eq "Microsoft.AzureStack.Diagnostics.DataCollection") { $incompletedeploymentdate = Get-Date -format MM-dd-hhmm $incompletedeploymentfoldername = "-IncompleteDeployment_AzureStackLogs" $incompletedeploymentsharename = $incompletedeploymentdate + $incompletedeploymentfoldername If (!(Test-Path "$($Env:SystemDrive)\$($incompletedeploymentsharename)")) {$incompletedeploymentfolder = New-Item -Path "$($Env:SystemDrive)\$($incompletedeploymentsharename)" -ItemType directory} Get-AzureStackLogs -OutputPath $incompletedeploymentfolder.FullName -FilterByRole $FilterByRole -FromDate $FromDate -ToDate $ToDate } Else { Write-Host "`n[Error] unable to load Microsoft.AzureStack.Diagnostics.DataCollection: $_" -ForegroundColor Red $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } #remotepowershell $s = New-PSSession -ComputerName $IP -ConfigurationName PrivilegedEndpoint -Credential $mySecureCredentials Try { Write-Host "`n `t[INFO] Getting Azure Stack stamp information" -ForegroundColor Green Invoke-Command -Session $s -ScriptBlock {Get-AzureStackStampInformation -WarningAction SilentlyContinue} -OutVariable StampInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster} -OutVariable ClusterDiskInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster | Get-StorageJob } -OutVariable ActiveStorageRepairs -WarningAction SilentlyContinue | Out-Null Write-Host "`n `t[INFO] Saving AzureStackStampInformation to $($Env:ProgramData)" -ForegroundColor Green #overwriting AzureStackStampInformation keep the latest info JSON (StampVersion) $StampInformation | ConvertTo-Json | Out-File -FilePath "$($Env:ProgramData)\AzureStackStampInformation.json" -Force Write-Host "`n `t[INFO] Saving AzureStackStampInformation to $($Env:SystemDrive)\$($incompletedeploymentsharename)" -ForegroundColor Green $StampInformation | ConvertTo-Json | Out-File -FilePath "$($Env:SystemDrive)\$($incompletedeploymentsharename)\AzureStackStampInformation.json" -Force $ClusterDiskInformation | Out-File -FilePath "$($Env:SystemDrive)\$($incompletedeploymentsharename)\ClusterVirtualDiskInfo.txt" -Force } catch { Write-Host "`n[Error] unable to connect to PEP: $_" -ForegroundColor Red } #zip files try { Write-Host "`n`t[INFO] Compressing gathered files" -ForegroundColor Green $zipdate = $incompletedeploymentdate if((Test-Path -Path $Env:SystemDrive\CloudDeployment\Logs) -eq $true) {Compress-Archive -Path (Get-ChildItem -Path $Env:SystemDrive\CloudDeployment\Logs).FullName -CompressionLevel Optimal -DestinationPath "$Env:SystemDrive\$incompletedeploymentsharename\$($zipdate)_CloudDeploymentLogs_archive.zip" -Force} if((Test-Path -Path $Env:SystemDrive\MASLogs) -eq $true) {Compress-Archive -Path (Get-ChildItem -Path $Env:SystemDrive\MASLogs).FullName -CompressionLevel Optimal -DestinationPath "$Env:SystemDrive\$incompletedeploymentsharename\$($zipdate)_MASLogs_archive.zip" -Force} Compress-Archive -Path (Get-ChildItem -Path $Env:SystemDrive\$incompletedeploymentsharename).FullName -CompressionLevel Optimal -DestinationPath "$Env:SystemDrive\$incompletedeploymentsharename\$($zipdate)_AzureStackLogs_archive.zip" -Force Write-Host "`tFile created: $Env:SystemDrive\$incompletedeploymentsharename\$($zipdate)_AzureStackLogs_archive.zip" -ForegroundColor White Invoke-Item $incompletedeploymentfolder.FullName Write-Host "`n `t[INFO] Opening $($incompletedeploymentfolder.FullName)" -ForegroundColor Green } catch { Write-Host "`n`t`t[WARN] Did not create a archive" -ForegroundColor Yellow } #cleanup exit } #setting remotepowershell options $switch = $true If($switch) { $switch = "Get-AzureStackLog -OutputSharePath `$using:ShareINFO -OutputShareCredential `$using:shareCred -ErrorAction Stop " $Howto = "Get-AzureStackLog -OutputSharePath `"$($ShareINFO)`" -OutputShareCredential `$using:cred " } If($FromDate) { $switch += "-FromDate `$using:fromDate " $Howto += "-FromDate `"$($FromDate)`" " } If($ToDate) { $switch += "-ToDate `$using:ToDate " $Howto += "-ToDate `"$($ToDate)`" " } #future use Switch($Scenario) { "Service Fabric" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Storage" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Networking" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Identity" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Patch & Update" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Compute" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} "Backup" {<#$FilterByRole += "Something1","Something2","Something3","Something4","ETC"#>} } If($FilterByRole) { $switch += "-FilterByRole `$using:FilterByRole " $Howto += "-FilterByRole `"$($FilterByRole)`" " } Write-Host "`n" Write-Host -NoNewline " `t[INFO] Running:" -ForegroundColor White Write-Host -NoNewline " Enter-PSSession -ComputerName $($IP) -ConfigurationName PrivilegedEndpoint -Credential `$cred" -ForegroundColor Green Write-Host "`n" Write-Host -NoNewline " `t[INFO] Running:" -ForegroundColor White Write-Host -NoNewline " $($Howto)" -ForegroundColor Green Write-Host "`n" #remotepowershell $s = New-PSSession -ComputerName $IP -ConfigurationName PrivilegedEndpoint -Credential $mySecureCredentials Try { #do stuff on the remote machine $ScriptBlock = [scriptblock]::Create($switch) $Job = Invoke-Command -Session $s -ScriptBlock $ScriptBlock -AsJob while((get-job -Id $job.id).State -eq "Running") { $per = (Get-Random -Minimum 5 -Maximum 80); Start-Sleep -Milliseconds 1500 Write-Progress -Activity "Please wait while Get-AzureStackLog is running on $($IP)" -PercentComplete $per } if((get-job -Id $job.id).State -eq "Failed") { Write-Progress -Activity "Please wait while Get-AzureStackLog is running on $($IP)" -Status "Ready" -Completed Write-Host "`n `t[INFO] Getting Azure Stack stamp information" -ForegroundColor Green Invoke-Command -Session $s -ScriptBlock {Get-AzureStackStampInformation -WarningAction SilentlyContinue} -OutVariable StampInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster} -OutVariable ClusterDiskInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster | Get-StorageJob } -OutVariable ActiveStorageRepairs -WarningAction SilentlyContinue | Out-Null } if((get-job -Id $job.id).State -eq "Completed") { Write-Progress -Activity "Please wait while Get-AzureStackLog is running on $($IP)" -Status "Ready" -Completed Write-Host "`n `t[INFO] Getting Azure Stack stamp information" -ForegroundColor Green Invoke-Command -Session $s -ScriptBlock {Get-AzureStackStampInformation -WarningAction SilentlyContinue} -OutVariable StampInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster} -OutVariable ClusterDiskInformation -WarningAction SilentlyContinue | Out-Null Invoke-Command -Session $s -ScriptBlock {Get-VirtualDisk -CimSession S-Cluster | Get-StorageJob } -OutVariable ActiveStorageRepairs -WarningAction SilentlyContinue | Out-Null } #output of files from the PEP if($StampInformation) { Write-Host "`n `t[INFO] Saving AzureStackStampInformation to $($Env:ProgramData)" -ForegroundColor Green #overwriting AzureStackStampInformation keep the latest info JSON (StampVersion) $StampInformation | ConvertTo-Json | Out-File -FilePath "$($Env:ProgramData)\AzureStackStampInformation.json" -Force Write-Host "`n `t[INFO] Saving AzureStackStampInformation to $($Env:SystemDrive)\$($sharename)" -ForegroundColor Green $StampInformation | ConvertTo-Json | Out-File -FilePath "$($Env:SystemDrive)\$($sharename)\AzureStackStampInformation.json" -Force $ClusterDiskInformation | Out-File -FilePath "$($Env:SystemDrive)\$($sharename)\ClusterVirtualDiskInfo.txt" -Force } if($CheckADSK -ne 1) { # output for transcript mutinode try { Write-Host "`n `t[INFO] Getting Azure Stack transcript" -ForegroundColor Green Invoke-Command -Session $s -ScriptBlock {Close-PrivilegedEndpoint -TranscriptsPathDestination $using:ShareINFO -Credential $using:shareCred -ErrorAction SilentlyContinue -WarningAction SilentlyContinue} -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } catch [System.Management.Automation.RemoteException] { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red } } else { Try { # output for transcript ASDK Write-Host "`n `t[INFO] Getting Azure Stack transcript" -ForegroundColor Green Invoke-Command -Session $s -ScriptBlock {Close-PrivilegedEndpoint -TranscriptsPathDestination "\\127.0.0.1\C`$" -WarningAction SilentlyContinue} -WarningAction SilentlyContinue $Transcript = Get-ChildItem -Path "\\$($IP)\C`$" | Where {($_.Name -like "Transcripts_*")} | sort -Descending -Property CreationTime | select -first 1 #copy the transcript to share Copy-Item -Path $Transcript.FullName -Destination $ShareINFO -Force #test to make sure the transcript is copied $localtranscript = Test-Path -Path "$($shareinfo)\$($Transcript.Name)" if ($localtranscript -eq $true) {Remove-Item -Path $Transcript.FullName -Force} } catch [System.Management.Automation.RemoteException] { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red } } } finally { Remove-PSSession $s } #get files for user $Files = Get-ChildItem -Path "$($Env:SystemDrive)\$($sharename)" | Where {(($_.attributes -eq 'directory') -and ($_.Name -like "AzureStackLogs-*"))} | sort -Descending -Property CreationTime | select -first 1 #look at output AzureStackLog_Output for issues $stacklog = Get-ChildItem -Path "$($Files.FullName)" | Where {($_.Name -like "Get-AzureStackLog_Output*")} | sort -Descending -Property CreationTime | select -first 1 $stacklogerr = Select-String -Path $stacklog.FullName -Pattern "TerminatingError" $stacklogeerrdisk = Select-String -Path $stacklog.FullName -Pattern "There is not enough space on the disk." $stacklogeerrcode = Select-String -Path $stacklog.FullName -Pattern "0x85200001" if($stacklog) { Write-Host "`n`t[INFO] Reviewing Get-AzureStackLog_Output.log for known issues" -ForegroundColor Green if(!($stacklogerr)) { Write-Host "`tNo issues found" -ForegroundColor White } } else { Write-Host "`t`t[ERROR] Get-AzureStackLog_Output.log file not found. Likely missing log files" -ForegroundColor Red } if($stacklogerr) { Write-Host "`t`t[ERROR] Get-AzureStackLog_Output.log has an terminating error" -ForegroundColor Red } if ($stacklogeerrdisk -and $stacklogerr) { Write-Host "`t`t`tERCS VM does not have enough space on the disk. Try lowering the log collection time." } if ($stacklogeerrcode -and $stacklogerr) { Write-Host "`t`t`t0x85200001" } #look at cluster disk state $ErrorClustervdisk = 0 Write-Host "`n`t[INFO] Checking Vitual Disk state" -ForegroundColor Green foreach ($clusterdisk in $ClusterDiskInformation) { if ($clusterdisk.HealthStatus -ne 0) { Write-Host "`t[ERROR] $($clusterdisk.FriendlyName) is not healthy" -ForegroundColor Red $ErrorClustervdisk += 1 } } switch ($ErrorClustervdisk) { '0' {Write-Host "`tNo issues found" -ForegroundColor White} '1' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '2' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '3' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '4' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '5' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '6' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '7' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '8' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '9' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '10' {Write-Host "`n`t[INFO] In the PEP run 'Get-VirtualDisk -CimSession S-Cluster | Repair-VirtualDisk'" -ForegroundColor Yellow} '11' {Write-Host "`n`t[INFO] Likely Node missing from cluster" -ForegroundColor Yellow} Default {Write-Host "`t[ERROR] Unexpected disk number"} } If ($ActiveStorageRepairs) { Write-Host "`n`t[WARNING] VirtualDisk repairs in progress" -ForegroundColor Yellow Write-Host "$($ActiveStorageRepairs)" } if($Files) { try { Write-Host "`n`t[INFO] Compressing gathered files" -ForegroundColor Green $zipdate = $date Compress-Archive -Path (Get-ChildItem -Exclude Transcripts_* -Path $Env:SystemDrive\$sharename).FullName -CompressionLevel Optimal -DestinationPath "$Env:SystemDrive\$sharename\$($zipdate)_AzureStackLogs_archive.zip" -Force Write-Host "`tFile created: $Env:SystemDrive\$sharename\$($zipdate)_AzureStackLogs_archive.zip" -ForegroundColor White Invoke-Item $Files.Parent.FullName Write-Host "`n `t[INFO] Opening $($Files.Parent.FullName)" -ForegroundColor Green } catch { Write-Host "`n`t`t[WARN] Did not create a archive" -ForegroundColor Yellow } } } catch [System.Management.Automation.ValidationMetadataException] { Write-Host "`n`t[ERROR] Incorrect password supplied, Access is denied" -ForegroundColor Red } catch [System.Management.Automation.RemoteException] { Write-Host "`n`t[ERROR] Incorrect password supplied, Access is denied" -ForegroundColor Red } catch [System.Exception] { Write-Host "`n`t`t[Error] Exception caught: $_" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } finally { Remove-SmbShare -Name $sharename -Force Remove-NetFirewallRule -Group "AzureStack_ERCS" Write-Host "`n `tPress any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit } } else { Write-Host "`n`t[INFO] Unable to find ip address of Emergency Recovery Console Session" -ForegroundColor Red Write-Host "`n Press any key to continue ...`n" $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") exit }