Stop Hunting for Web Servers: How to Auto-Discover Every IIS Instance in Your Domain

Posted on Updated on

IIS Discovery

Have you ever been asked for a list of every active web server in your environment, only to realize your documentation is six months out of date? You could check your DNS records manually, or you could let PowerShell do the detective work for you.

This script scans your Active Directory for Windows Servers, checks if the World Wide Web Publishing Service (W3SVC) is actually running, and then pulls a deep-profile of the hardware, OS, and network configuration for every active hit.

The Setup

  1. Create the workspace: Create a folder at C:\Temp\ServersRunningIIS.
  2. Prepare the list: The script will automatically generate a list of all Windows Servers from AD, but ensure you have the Active Directory PowerShell module installed.
  3. Run with Privileges: Since the script uses WMI to query remote system info (RAM, OS Version, etc.), run your PowerShell ISE or Console as a Domain Admin.

The PowerShell Script

PowerShell
# Script: IIS Server Discovery & Profiler
# Location: lazyadminblog.com
# Purpose: Identify active IIS nodes and collect hardware/OS specs
Import-Module ActiveDirectory
# 1. Harvest all Windows Servers from AD
Write-Host "Gathering server list from Active Directory..." -ForegroundColor Cyan
$servers = Get-ADComputer -Filter {operatingsystem -Like "Windows server*"} | Select-Object -ExpandProperty Name
$servers | Out-File "C:\Temp\ServersRunningIIS\serverlist.txt"
# 2. Load the list for processing
$serversall = Get-Content "C:\Temp\ServersRunningIIS\serverlist.txt"
Start-Transcript -Path "C:\Temp\ServersRunningIIS\log_output.txt" -Append
foreach($vm in $serversall) {
try {
# Check if IIS Service (W3SVC) exists and is running
$iis = Get-WmiObject Win32_Service -ComputerName $vm -Filter "name='W3SVC'" -ErrorAction SilentlyContinue
if($iis.State -eq "Running") {
Write-Host "FOUND: IIS is active on $vm" -BackgroundColor DarkBlue -ForegroundColor DarkYellow
# Collect Network Info
$ipinfo = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $vm |
Where-Object {$_.IPEnabled -eq $true -and $_.IPAddress -like "1*"} | Select-Object -First 1
# Collect Hardware Info
$hwinfo = Get-WmiObject Win32_Computersystem -ComputerName $vm
# Collect OS Info
$osinfo = Get-WmiObject Win32_OperatingSystem -ComputerName $vm
# Flattening data for CSV-style output
$allinfo = "$($hwinfo.Name);$($hwinfo.Domain);$($ipinfo.IPAddress);$($ipinfo.IPSubnet);$($ipinfo.DefaultIPGateway);$($hwinfo.TotalPhysicalMemory);$($hwinfo.Manufacturer);$($hwinfo.Model);$($osinfo.Caption);$($osinfo.OSArchitecture);$($osinfo.ServicePackMajorVersion);$($osinfo.SystemDrive);$($osinfo.Version)"
# Save results to our 'Running' list
$allinfo | Out-File "C:\Temp\ServersRunningIIS\RunningWebServers.txt" -Append
}
}
catch {
Write-Host "Could not connect to $vm" -ForegroundColor Red
}
}
Stop-Transcript
Write-Host "Audit Complete! Check C:\Temp\ServersRunningIIS\RunningWebServers.txt" -ForegroundColor Green

Whatโ€™s inside the report?

The output file (RunningWebServers.txt) uses a semicolon (;) delimiter, making it easy to import into Excel. It captures:

  • Network: IP Address, Subnet, and Gateway.
  • Hardware: Manufacturer, Model, RAM, and Domain membership.
  • Software: OS Version, Architecture (x64/x86), and System Drive.

Lazy Admin Tip

If you want to open the results immediately in Excel, just rename the output file from .txt to .csv and use the “Text to Columns” feature in Excel with the semicolon as the separator!

The Architectโ€™s Guide to Windows 12: AI, CorePC, and the Infrastructure Pivot | LazyAdminBlog.com

Posted on Updated on

The era of the “monolithic OS” is officially ending. General users will enjoy the “Floating Taskbar” and AI-driven search. Infrastructure architects need to focus on two structural pillars: CorePC and NPU-driven compute.

1. The CorePC Transformation: State-Separated Architecture

For decades, Windows has been a “monolithic” block of code where system files, drivers, and user data were loosely intertwined. Windows 12 introduces CorePC, a modular architecture built on State Separation.

What is State Separation?

CorePC breaks the OS into isolated, specialized partitions. This design philosophy comes from mobile operating systems like iOS and Android. It is adapted for the complexity of the PC.

  • The System Partition: A read-only, digitally signed, and immutable image provided by Microsoft. It is isolated from everything else.
  • The Application Layer: Apps are containerized. They can interact with system files but cannot modify them, preventing “registry rot” and unauthorized system changes.
  • The User State: The only mutable partition where user profiles and local data reside.

๐Ÿ’ก Architectโ€™s Insight: The Death of “WinRot”

Practical Application: In a traditional enterprise, a corrupted system file often requires a full re-image. With State Separation, the OS can perform an Atomic Update. It swaps the entire read-only system partition for a fresh one in the background. For a help desk, this means “Reset this PC” takes seconds rather than hours. User data remains completely untouched. It lives on a separate logical “state.”


2. The NPU Requirement: 40+ TOPS or Bust

If your 2026 hardware budget doesn’t prioritize the NPU (Neural Processing Unit), your fleet will be obsolete on delivery.

Understanding TOPS (Trillions of Operations Per Second)

TOPS is the “horsepower” rating for an NPU. Think of it as the RPM for your AI engine. CPUs are great at logic, and GPUs excel at graphics. NPUs are specialized silicon designed to handle the trillions of matrix multiplications required by AI models. They achieve this without draining the battery.

  • The Threshold: Microsoft has set a benchmark of 40+ TOPS.
  • Why it matters: Windows 12 uses a Neural Index for Recall and Semantic Search. This allows users to find a file by describing it (e.g., “Find the blue sustainability slide from last meeting”) rather than remembering a filename.
  • The Hardware Gate: To handle this locally (for privacy and speed), dedicated silicon is required. Current leaders include the Snapdragon X Elite, Intel Core Ultra, and AMD Ryzen AI series.

๐Ÿ’ก Architectโ€™s Insight: VDI and the “AI Gap”

The Real-World Scenario: If you are a VDI architect, Windows 12 presents a challenge. Most hypervisors do not yet support NPU passthrough. Running Windows 12 in a VM without NPU offloading means features like Recall will either be disabled. Alternatively, they will tax the server CPUs to the point of instability. Strategy: Shift non-NPU-capable legacy endpoints to Windows 365 (Cloud PC). This offloads the AI compute to Microsoftโ€™s Azure hardware. Older thin clients can “run” Windows 12 features they couldn’t handle locally.


3. Implementation Roadmap: 2026 Action Plan

Phase 1: The “NPU-Ready” Audit

Stop purchasing “standard” laptops. 16GB RAM is now the absolute minimum for AI-native workloads. If you use 8GB, it will lead to significant performance bottlenecks because local models will swap to disk.

Phase 2: AI Data Governance

Windows 12 will “see” and “index” local content via Smart Recall.

  • Action: You must define Intune/GPO policies to govern what is indexed. You don’t want the OS indexing sensitive PII or passwords that might appear on-screen during a session. Microsoft has built exclusion logic for credential-related content, but enterprise-grade filtering is still a requirement.

โ“ Frequently Asked Questions (FAQ)

  • Will my legacy Win32 apps still work? Yes. Windows 12 uses a Win32 Container to run classic apps. However, kernel-mode drivers (like old VPN clients) may need modernization to support the new state-separated driver model.
  • Is Windows 12 mandatory? Technically, no. Windows 11 continues to receive updates. Windows 10 is reaching the end of its Extended Security Update (ESU) lifecycle. Therefore, adopting the modular architecture of Windows 12 is the only long-term path for security compliance.
  • What about privacy with “Recall”? All Recall indexing and AI processing occur on-device. No screenshots or semantic data are sent to the cloud. Access is protected by Windows Hello (biometrics).

๐Ÿ Summary: Key Takeaways for the Busy Architect

  1. Modular OS: Windows 12 uses CorePC for faster, safer updates and near-instant recovery.
  2. Silicon-First: A 40+ TOPS NPU is mandatory for the full “AI PC” experience.
  3. VDI Pivot: Use Windows 365 to bridge the gap for legacy hardware that lacks local AI silicon.

Whatโ€™s your strategy for the NPU transition? Are you leaning toward a hardware refresh or a shift to Cloud PCs?

Share your thoughts in the comments. Let us know if you want a follow-up post on Intune policies for Smart Recall governance!

Build Your Own VM Snapshot GUI with PowerShell | LazyAdminBlog.com

Posted on Updated on

Build Your Own VM Snapshot GUI with PowerShell

The ultimate “I’m too busy for CLI” tool for VMware Admins.

Today, I am sharing a complete PowerShell tool that creates a custom Windows Form to manage bulk snapshots across multiple vCenters, complete with a progress bar and an automated HTML email report.

๐Ÿš€ What this tool does:

  • Multi-vCenter Support: Toggle between environments with simple radio buttons.
  • Bulk Processing: Paste a list of hostnames directly into the text box.
  • Smart Memory Handling: Choose whether to include VM memory in the snapshot.
  • Progress Tracking: A real-time progress bar so you know exactly when it’s safe to go grab another coffee.
  • Automated Reporting: Generates a CSV on your desktop and sends a formatted HTML email to your team.

The Script: VM-Snapshot-GUI.ps1

Lazy Admin Note: Before running, make sure you have the VMware PowerCLI module installed. Change the "SMTP Server" and "From@domain.com" strings in the script to match your environment.

<!-- wp:syntaxhighlighter/code -->
<pre class="wp-block-syntaxhighlighter-code">Function Snapshot()
{
    Add-Type -AssemblyName System.Drawing
    Add-Type -AssemblyName System.Windows.Forms
    
    # Create the Main form.
    $form = New-Object System.Windows.Forms.Form 
    $form.Text = "VM Snapshot"
    $form.Size = New-Object System.Drawing.Size(650,320)
    $form.FormBorderStyle = 'FixedSingle'
    $form.StartPosition = "CenterScreen"
    $form.AutoSizeMode = 'GrowAndShrink'
    $form.Topmost = $True
    $form.ShowInTaskbar = $true  

    # Create the Email form.
    $Emailform = New-Object System.Windows.Forms.Form 
    $Emailform.Text = "Email Report"
    $Emailform.Size = New-Object System.Drawing.Size(420,200)
    $Emailform.FormBorderStyle = 'FixedSingle'
    $form.StartPosition = "CenterScreen"
    $Emailform.AutoSizeMode = 'GrowAndShrink'
    $Emailform.Topmost = $True
    $Emailform.ShowInTaskbar = $true  
    
    #Select vCenter
    $groupBox = New-Object System.Windows.Forms.GroupBox
    $groupBox.Location = New-Object System.Drawing.Size(10,20) 
    $groupBox.size = New-Object System.Drawing.Size(180,80) 
    $groupBox.text = "Select the vCenter:" 
    $Form.Controls.Add($groupBox) 

    $RadioButton1 = New-Object System.Windows.Forms.RadioButton 
    $RadioButton1.Location = new-object System.Drawing.Point(15,15) 
    $RadioButton1.size = New-Object System.Drawing.Size(160,25) 
    $RadioButton1.Checked = $true 
    $RadioButton1.Text = "vCenter 1" 
    $groupBox.Controls.Add($RadioButton1) 

    $RadioButton2 = New-Object System.Windows.Forms.RadioButton
    $RadioButton2.Location = new-object System.Drawing.Point(15,40)
    $RadioButton2.size = New-Object System.Drawing.Size(160,25)
    $RadioButton2.Text = "vCenter 2"
    $groupBox.Controls.Add($RadioButton2)

    #Select Snapshot memory
    $groupBox1 = New-Object System.Windows.Forms.GroupBox
    $groupBox1.Location = New-Object System.Drawing.Size(200,20) 
    $groupBox1.size = New-Object System.Drawing.Size(180,80) 
    $groupBox1.text = "Snapshot Memory:" 
    $Form.Controls.Add($groupBox1) 

    $RadioButton3 = New-Object System.Windows.Forms.RadioButton 
    $RadioButton3.Location = new-object System.Drawing.Point(15,15) 
    $RadioButton3.size = New-Object System.Drawing.Size(160,25) 
    $RadioButton3.Checked = $true 
    $RadioButton3.Text = "Snapshot Without Memory" 
    $groupBox1.Controls.Add($RadioButton3) 

    $RadioButton4 = New-Object System.Windows.Forms.RadioButton
    $RadioButton4.Location = new-object System.Drawing.Point(15,40)
    $RadioButton4.size = New-Object System.Drawing.Size(160,25)
    $RadioButton4.Text = "Snapshot With Memory"
    $groupBox1.Controls.Add($RadioButton4)
    
    $label = New-Object System.Windows.Forms.Label
    $label.Location = New-Object System.Drawing.Size(390,20) 
    $label.Size = New-Object System.Drawing.Size(280,20)
    $label.AutoSize = $true
    $label.Text = "Enter Hostname Here..."

    # Create the TextBox used to capture the user's text.
    $textBox = New-Object System.Windows.Forms.TextBox 
    $textBox.Location = New-Object System.Drawing.Size(390,40) 
    $textBox.Size = New-Object System.Drawing.Size(130,230)
    $textBox.AcceptsReturn = $true
    $textBox.AcceptsTab = $false
    $textBox.Multiline = $true
    $textBox.ScrollBars = 'Both'
    $textbox.CharacterCasing='Upper'

    # Getting Input for Snapshot SR#, Snapshot Name, Snapshot Description.
    $SR_label = New-Object System.Windows.Forms.Label
    $SR_label.Location = New-Object System.Drawing.Size(15,130) 
    $SR_label.Size = New-Object System.Drawing.Size(280,20)
    $SR_label.AutoSize = $true
    $SR_label.Text = "*SR#"

    $SR_textBox = New-Object System.Windows.Forms.TextBox 
    $SR_textBox.Location = New-Object System.Drawing.Size(150,130) 
    $SR_textBox.Size = New-Object System.Drawing.Size(130,20)
    $SR_textBox.AcceptsReturn = $true
    $SR_textBox.AcceptsTab = $false
    $SR_textbox.CharacterCasing='Upper'
    
    $SN_label = New-Object System.Windows.Forms.Label
    $SN_label.Location = New-Object System.Drawing.Size(15,160) 
    $SN_label.Size = New-Object System.Drawing.Size(280,20)
    $SN_label.AutoSize = $true
    $SN_label.Text = "*Snapshot Name"
    
    $SN_textBox = New-Object System.Windows.Forms.TextBox 
    $SN_textBox.Location = New-Object System.Drawing.Size(150,160) 
    $SN_textBox.Size = New-Object System.Drawing.Size(200,20)
    $SN_textBox.AcceptsReturn = $true
    $SN_textBox.AcceptsTab = $false
    #$SN_textbox.CharacterCasing='Upper'

    $SD_label = New-Object System.Windows.Forms.Label
    $SD_label.Location = New-Object System.Drawing.Size(15,190) 
    $SD_label.Size = New-Object System.Drawing.Size(280,20)
    $SD_label.AutoSize = $true
    $SD_label.Text = "Snapshot Description"

    $SD_textBox = New-Object System.Windows.Forms.TextBox 
    $SD_textBox.Location = New-Object System.Drawing.Size(150,190) 
    $SD_textBox.Size = New-Object System.Drawing.Size(200,50)
    $SD_textBox.AcceptsReturn = $true
    $SD_textBox.AcceptsTab = $false
    $SD_textBox.Multiline = $true
    $SD_textBox.ScrollBars = 'Both'
    #$SD_textbox.CharacterCasing='Upper'
        
    #Create the Hardening Button.
    $HButton = New-Object System.Windows.Forms.Button
    $HButton.Location = New-Object System.Drawing.Size(540,40)
    $HButton.Size = New-Object System.Drawing.Size(100,40)
    $HButton.Text = "Take Snapshot"

    #Create the Report Button.
    $RButton = New-Object System.Windows.Forms.Button
    $RButton.Location = New-Object System.Drawing.Size(540,90)
    $RButton.Size = New-Object System.Drawing.Size(100,40)
    $RButton.Text = "Generate Report"

    #Create the Report Button.
    $EmailButton = New-Object System.Windows.Forms.Button
    $EmailButton.Location = New-Object System.Drawing.Size(540,140)
    $EmailButton.Size = New-Object System.Drawing.Size(100,40)
    $EmailButton.Text = "Send Email"

    #Create the Progress-Bar.
    $label1 = New-Object System.Windows.Forms.Label
    $label1.Location = New-Object System.Drawing.Size(20,230) 
    $label1.Size = New-Object System.Drawing.Size(280,20)
    $label1.AutoSize = $true
    $label1.Text = "Progress..."

    $PB = New-Object System.Windows.Forms.ProgressBar
	$PB.Name = "PowerShellProgressBar"
	$PB.Value = 0
	$PB.Style="Continuous"

    $System_Drawing_Size = New-Object System.Drawing.Size
	$System_Drawing_Size.Width = 200 - 40
	$System_Drawing_Size.Height = 20
	$PB.Size = $System_Drawing_Size
	$PB.Left = 20
	$PB.Top = 250
    
    #Initiate Snapshot
    $HButton.Add_Click(
    { 
        $report= @()
        $counter = 0
        If ($SR_textBox.TextLength -ne 0 -and $SN_textBox.TextLength -ne 0)
        {
                $S_Name= $SR_textBox.text+ " - " +$SN_textBox.text  
        }
        Else{
            [System.Windows.Forms.MessageBox]::Show("SR# or Snapshot Name cannot be blank", "Info")
            return
        }
	   
        If ($textbox.TextLength -eq 0)
        {
            [System.Windows.Forms.MessageBox]::Show("Server List is empty", "Info")
            return       
        }
        [System.Windows.Forms.MessageBox]::Show("Sit back and relax while Snapshot is taken !!!", "VM Snapshot")
        $ServerList=$textbox.Text.Split("`n")|%{$_.trim()}
        Foreach ($vm in $ServerList)
        {
            if($vm -eq "")
            {
                $counter++
                [Int]$Percentage = ($Counter/$ServerList.Count)*100
                $PB.Value = $Percentage
                continue
            }
                
            if ($RadioButton1.Checked -eq $True) 
            {
                Add-PSSnapin VMware.VimAutomation.Core
                Connect-VIServer -Server vCenter1
            }
            if ($RadioButton2.Checked -eq $True) 
            {
                Add-PSSnapin VMware.VimAutomation.Core
                Connect-VIServer -Server vCenter2
            }
            $Exists = get-vm -name $vm -ErrorAction SilentlyContinue
            If ($Exists)
            {
                If ($RadioButton3.Checked -eq $True)
                {
                    Get-VM $vm |New-snapshot -Name $S_Name -Description $SD_textBox.Text
                    $rep = Get-VM $vm | Get-Snapshot | Select-Object @{Name='VM';Expression={$_.vm}},@{Name='Snapshot_Name';Expression={$_.name}},@{Name='Description';Expression={$_.Description}},@{Name='Created';Expression={$_.Created}},@{Name='Remarks';Expression={""}}
                    $report = $report + $rep
                }
                If ($RadioButton4.Checked -eq $True)
                {
                    Get-VM $vm |New-snapshot -Name $S_Name -Description $SD_textBox.Text -Memory
                    $rep = Get-VM $vm | Get-Snapshot | Select-Object @{Name='VM';Expression={$_.vm}},@{Name='Snapshot_Name';Expression={$_.name}},@{Name='Description';Expression={$_.Description}},@{Name='Created';Expression={$_.Created}},@{Name='Remarks';Expression={""}}
                    $report = $report + $rep
                }
            }
            If (!$Exists)
            {
                $row= New-Object PSObject -Property @{VM = $vm;Snapshot_Name = "";Description = "";Created = "";Remarks="Server not Found"}
                $report += $row
            }
            $counter++
            [Int]$Percentage = ($Counter/$ServerList.Count)*100
            $PB.Value = $Percentage
        }
        [System.Windows.Forms.MessageBox]::Show("Snapshot taken successfully" , "Report Generation")
        $report |Select-object @{Name="HOSTNAME"; Expression={$_.VM}},@{Name="Snapshot_Name"; Expression={$_.Snapshot_Name}},@{Name="Description"; Expression={$_.Description}},@{Name="Created: Date &amp; Time"; Expression={$_.Created}},@{Name='Remarks';Expression={$_.Remarks}}| Export-Csv $file -NoTypeInformation
    })

    #Report Generation
    $RButton.Add_Click(
    {    
		ii $path
    })

    #Send Email
    $EmailButton.Add_Click(
    {   
        #Create Label
        $ToLabel = New-Object System.Windows.Forms.Label
        $ToLabel.Location = New-Object System.Drawing.Size(20,20) 
        $ToLabel.Size = New-Object System.Drawing.Size(100,20)
        $ToLabel.AutoSize = $true
        $ToLabelFont = New-Object Drawing.Font("Times New Roman",12,[System.Drawing.FontStyle]::Bold)
        $ToLabel.Font = $ToLabelFont
        $ToLabel.Text = "*To:"

        $CcLabel = New-Object System.Windows.Forms.Label
        $CcLabel.Location = New-Object System.Drawing.Size(20,50) 
        $CcLabel.Size = New-Object System.Drawing.Size(100,20)
        $CcLabel.AutoSize = $true
        $CcLabelFont = New-Object Drawing.Font("Times New Roman",12,[System.Drawing.FontStyle]::Bold)
        $CcLabel.Font = $CcLabelFont
        $CcLabel.Text = "Cc: (Optional)"

        #Create the TextBox Email Address.
        $ToBox = New-Object System.Windows.Forms.TextBox 
        $ToBox.Location = New-Object System.Drawing.Size(140,20) 
        $ToBox.Size = New-Object System.Drawing.Size(250,20)
        $ToBoxFont = New-Object Drawing.Font("Times New Roman",8)
        $ToBox.Font=$ToBoxFont
        $ToBox.AcceptsReturn = $true
        $ToBox.AcceptsTab = $false
        #$ToBox.text=""
        $ToBox.CharacterCasing='lower'

        $CcBox = New-Object System.Windows.Forms.TextBox 
        $CcBox.Location = New-Object System.Drawing.Size(140,50) 
        $CcBox.Size = New-Object System.Drawing.Size(250,20)
        $CcBoxFont = New-Object Drawing.Font("Times New Roman",8)
        $CcBox.Font=$CcBoxFont
        $CcBox.AcceptsReturn = $true
        $CcBox.AcceptsTab = $false
        $CcBox.text=""
        $CcBox.CharacterCasing='lower'
        
        #Create Email Send Button
        $SendButton = New-Object System.Windows.Forms.Button
        $SendButton.Location = New-Object System.Drawing.Size(20,100)
        $SendButton.Size = New-Object System.Drawing.Size(100,40)
        $ButtonFont = New-Object Drawing.Font("Times New Roman",8,[System.Drawing.FontStyle]::Bold)
        $SendButton.Font=$ButtonFont
        $SendButton.Text = "Send Email"

        $CancelButton = New-Object System.Windows.Forms.Button
        $CancelButton.Location = New-Object System.Drawing.Size(150,100)
        $CancelButton.Size = New-Object System.Drawing.Size(100,40)
        $CancelButton.Font=$ButtonFont
        $CancelButton.Text = "Cancel"

        $Emailform.Controls.Add($ToLabel)
        $Emailform.Controls.Add($CcLabel)
        $Emailform.Controls.Add($ToBox)
        $Emailform.Controls.Add($CCBox)
        $Emailform.Controls.Add($SendButton)
        $Emailform.Controls.Add($CancelButton)
        
        $SendButton.Add_Click(
        {
            If ($ToBox.Text.Length -eq 0)
            {
                [System.Windows.Forms.MessageBox]::Show("Email address cannot be empty" , "Email Info")
                return
            }
            #---------------------------------------------------------------------
            # Generate the HTML report and output to file
            #---------------------------------------------------------------------

            $head = "&lt;style>"
            $head = $head + "BODY{background-color:white;}"
            $head = $head + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
            $head = $head + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#778899}"
            $head = $head + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black}"
            $head = $head + "&lt;/style>"

            # SMTP info
            $Toemail=$ToBox.Text
            $strTo=$Toemail
            $strCc=$CCBox.Text
            $strSubject = "Snapshot Taken : $S_Name"
            $StrMsg="Hi All, &lt;br>Snapshot has been taken successfully for below list of servers &lt;br>&lt;br>"
            $strBody = "Attached is the list of Snapshots"
            $strMail = $strmsg

            # Write the output to an HTML file
            $strOutFile = $Path+"email.html"
            $ComputerName=(Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
            Get-Content -Path $File |ConvertFrom-CSV | ConvertTo-HTML  -Head $head -Body $StrMsg | Out-File $StrOutFile
            
	        # Mail the output file
	        $msg = new-object Net.Mail.MailMessage
	        $att = new-object Net.Mail.Attachment($File)
	        $smtp = new-object Net.Mail.SmtpClient("SMTP Server")
            $msg.From ="From@domain.com"
	        $msg.To.Add($strTo)
            If ($strCc.Length -ne 0)
            {
                $msg.cc.Add($strcc)
            }
	        $msg.Subject = $strSubject
	        $msg.IsBodyHtml = 1
	        $msg.Body = Get-Content $strOutFile
	        $msg.Attachments.Add($att)
            $smtp.Send($msg)
                [System.Windows.Forms.MessageBox]::Show("Email Send !!!","Info")
                $Emailform.close()
        })
        $CancelButton.Add_Click(
        {
            $Emailform.close()
        })
        $Emailform.Add_Shown({$Emailform.Activate()})
        $Emailform.ShowDialog() > $null 
               
    })
        
    # Add all of the controls to the form.
    $form.Controls.Add($label)
    $form.Controls.Add($textBox)
    $form.Controls.Add($groupBox)
    $form.Controls.Add($groupBox1)
    $form.Controls.Add($RButton)
    $form.Controls.Add($HButton)
    $form.Controls.Add($label1)
    $form.Controls.Add($SR_label)
    $form.Controls.Add($SR_textBox)
    $form.Controls.Add($SN_label)
    $form.Controls.Add($SN_textBox)
    $form.Controls.Add($SD_label)
    $form.Controls.Add($SD_textBox)
    $form.Controls.Add($PB)
    $form.Controls.Add($EmailButton)
    # Initialize and show the form.
    $form.Add_Shown({$form.Activate()})
    $form.ShowDialog() > $null
}
Set-ExecutionPolicy unrestricted -Force
$date=get-Date -format "ddMMyy_HHmm"
$ComputerName=(Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
$Path=[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop)+"\Report\"
If ((Test-Path $Path) -eq $false)
{
    New-Item $Path -type directory
}
New-Item -ErrorAction Ignore -ItemType directory -Path Report
$File=$Path + "SnapshotReport_$date.csv"
Snapshot</pre>
<!-- /wp:syntaxhighlighter/code -->

๐Ÿ› ๏ธ How to use the GUI:

  1. Select your vCenter: Choose which environment the VMs live in.
  2. Snapshot Specs: Enter the SR# (Service Request) and a Name. These are mandatory to keep your environment organized.
  3. Input Servers: Paste your list of servers (one per line) into the right-hand text box.
  4. Hit ‘Take Snapshot’: The tool will cycle through the list. If a server isn’t found, it won’t crash; it just marks it as “Server not Found” in your final report.
  5. Send Email: Once finished, click ‘Send Email’ to notify your team that the work is done.

Why this belongs in your toolkit:

The “Lazy Admin” way is about standardization. By using this GUI, every snapshot taken by your team will follow the same naming convention: SR# - Snapshot Name. No more guessing what “Snap1” or “Update_v2” means six months from now.

๐Ÿ› ๏ธ The Refactor: Adding the “Cleanup” Tab

In the code below, Iโ€™ve introduced the TabControl and TabPage classes. The new Cleanup Tab includes a feature every admin needs: Age-Based Filtering. It can scan for snapshots older than 2 or 3 days and wipe them in bulk.

<!-- wp:syntaxhighlighter/code -->
<pre class="wp-block-syntaxhighlighter-code">Function Snapshot()
{
ย  ย  Add-Type -AssemblyName System.Drawing
ย  ย  Add-Type -AssemblyName System.Windows.Forms
ย  ย ย 
ย  ย  # Create the Main form.
ย  ย  $form = New-Object System.Windows.Forms.Formย 
ย  ย  $form.Text = "VM Snapshot"
ย  ย  $form.Size = New-Object System.Drawing.Size(650,320)
ย  ย  $form.FormBorderStyle = 'FixedSingle'
ย  ย  $form.StartPosition = "CenterScreen"
ย  ย  $form.AutoSizeMode = 'GrowAndShrink'
ย  ย  $form.Topmost = $True
ย  ย  $form.ShowInTaskbar = $trueย ย 

ย  ย  # Create the Email form.
ย  ย  $Emailform = New-Object System.Windows.Forms.Formย 
ย  ย  $Emailform.Text = "Email Report"
ย  ย  $Emailform.Size = New-Object System.Drawing.Size(420,200)
ย  ย  $Emailform.FormBorderStyle = 'FixedSingle'
ย  ย  $form.StartPosition = "CenterScreen"
ย  ย  $Emailform.AutoSizeMode = 'GrowAndShrink'
ย  ย  $Emailform.Topmost = $True
ย  ย  $Emailform.ShowInTaskbar = $trueย ย 
ย  ย ย 
ย  ย  #Select vCenter
ย  ย  $groupBox = New-Object System.Windows.Forms.GroupBox
ย  ย  $groupBox.Location = New-Object System.Drawing.Size(10,20)ย 
ย  ย  $groupBox.size = New-Object System.Drawing.Size(180,80)ย 
ย  ย  $groupBox.text = "Select the vCenter:"ย 
ย  ย  $Form.Controls.Add($groupBox)ย 

ย  ย  $RadioButton1 = New-Object System.Windows.Forms.RadioButtonย 
ย  ย  $RadioButton1.Location = new-object System.Drawing.Point(15,15)ย 
ย  ย  $RadioButton1.size = New-Object System.Drawing.Size(160,25)ย 
ย  ย  $RadioButton1.Checked = $trueย 
ย  ย  $RadioButton1.Text = "vCenter 1"ย 
ย  ย  $groupBox.Controls.Add($RadioButton1)ย 

ย  ย  $RadioButton2 = New-Object System.Windows.Forms.RadioButton
ย  ย  $RadioButton2.Location = new-object System.Drawing.Point(15,40)
ย  ย  $RadioButton2.size = New-Object System.Drawing.Size(160,25)
ย  ย  $RadioButton2.Text = "vCenter 2"
ย  ย  $groupBox.Controls.Add($RadioButton2)

ย  ย  #Select Snapshot memory
ย  ย  $groupBox1 = New-Object System.Windows.Forms.GroupBox
ย  ย  $groupBox1.Location = New-Object System.Drawing.Size(200,20)ย 
ย  ย  $groupBox1.size = New-Object System.Drawing.Size(180,80)ย 
ย  ย  $groupBox1.text = "Snapshot Memory:"ย 
ย  ย  $Form.Controls.Add($groupBox1)ย 

ย  ย  $RadioButton3 = New-Object System.Windows.Forms.RadioButtonย 
ย  ย  $RadioButton3.Location = new-object System.Drawing.Point(15,15)ย 
ย  ย  $RadioButton3.size = New-Object System.Drawing.Size(160,25)ย 
ย  ย  $RadioButton3.Checked = $trueย 
ย  ย  $RadioButton3.Text = "Snapshot Without Memory"ย 
ย  ย  $groupBox1.Controls.Add($RadioButton3)ย 

ย  ย  $RadioButton4 = New-Object System.Windows.Forms.RadioButton
ย  ย  $RadioButton4.Location = new-object System.Drawing.Point(15,40)
ย  ย  $RadioButton4.size = New-Object System.Drawing.Size(160,25)
ย  ย  $RadioButton4.Text = "Snapshot With Memory"
ย  ย  $groupBox1.Controls.Add($RadioButton4)
ย  ย ย 
ย  ย  $label = New-Object System.Windows.Forms.Label
ย  ย  $label.Location = New-Object System.Drawing.Size(390,20)ย 
ย  ย  $label.Size = New-Object System.Drawing.Size(280,20)
ย  ย  $label.AutoSize = $true
ย  ย  $label.Text = "Enter Hostname Here..."

ย  ย  # Create the TextBox used to capture the user's text.
ย  ย  $textBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  $textBox.Location = New-Object System.Drawing.Size(390,40)ย 
ย  ย  $textBox.Size = New-Object System.Drawing.Size(130,230)
ย  ย  $textBox.AcceptsReturn = $true
ย  ย  $textBox.AcceptsTab = $false
ย  ย  $textBox.Multiline = $true
ย  ย  $textBox.ScrollBars = 'Both'
ย  ย  $textbox.CharacterCasing='Upper'

ย  ย  # Getting Input for Snapshot SR#, Snapshot Name, Snapshot Description.
ย  ย  $SR_label = New-Object System.Windows.Forms.Label
ย  ย  $SR_label.Location = New-Object System.Drawing.Size(15,130)ย 
ย  ย  $SR_label.Size = New-Object System.Drawing.Size(280,20)
ย  ย  $SR_label.AutoSize = $true
ย  ย  $SR_label.Text = "*SR#"

ย  ย  $SR_textBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  $SR_textBox.Location = New-Object System.Drawing.Size(150,130)ย 
ย  ย  $SR_textBox.Size = New-Object System.Drawing.Size(130,20)
ย  ย  $SR_textBox.AcceptsReturn = $true
ย  ย  $SR_textBox.AcceptsTab = $false
ย  ย  $SR_textbox.CharacterCasing='Upper'
ย  ย ย 
ย  ย  $SN_label = New-Object System.Windows.Forms.Label
ย  ย  $SN_label.Location = New-Object System.Drawing.Size(15,160)ย 
ย  ย  $SN_label.Size = New-Object System.Drawing.Size(280,20)
ย  ย  $SN_label.AutoSize = $true
ย  ย  $SN_label.Text = "*Snapshot Name"
ย  ย ย 
ย  ย  $SN_textBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  $SN_textBox.Location = New-Object System.Drawing.Size(150,160)ย 
ย  ย  $SN_textBox.Size = New-Object System.Drawing.Size(200,20)
ย  ย  $SN_textBox.AcceptsReturn = $true
ย  ย  $SN_textBox.AcceptsTab = $false
ย  ย  #$SN_textbox.CharacterCasing='Upper'

ย  ย  $SD_label = New-Object System.Windows.Forms.Label
ย  ย  $SD_label.Location = New-Object System.Drawing.Size(15,190)ย 
ย  ย  $SD_label.Size = New-Object System.Drawing.Size(280,20)
ย  ย  $SD_label.AutoSize = $true
ย  ย  $SD_label.Text = "Snapshot Description"

ย  ย  $SD_textBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  $SD_textBox.Location = New-Object System.Drawing.Size(150,190)ย 
ย  ย  $SD_textBox.Size = New-Object System.Drawing.Size(200,50)
ย  ย  $SD_textBox.AcceptsReturn = $true
ย  ย  $SD_textBox.AcceptsTab = $false
ย  ย  $SD_textBox.Multiline = $true
ย  ย  $SD_textBox.ScrollBars = 'Both'
ย  ย  #$SD_textbox.CharacterCasing='Upper'
ย  ย  ย  ย ย 
ย  ย  #Create the Hardening Button.
ย  ย  $HButton = New-Object System.Windows.Forms.Button
ย  ย  $HButton.Location = New-Object System.Drawing.Size(540,40)
ย  ย  $HButton.Size = New-Object System.Drawing.Size(100,40)
ย  ย  $HButton.Text = "Take Snapshot"

ย  ย  #Create the Report Button.
ย  ย  $RButton = New-Object System.Windows.Forms.Button
ย  ย  $RButton.Location = New-Object System.Drawing.Size(540,90)
ย  ย  $RButton.Size = New-Object System.Drawing.Size(100,40)
ย  ย  $RButton.Text = "Generate Report"

ย  ย  #Create the Report Button.
ย  ย  $EmailButton = New-Object System.Windows.Forms.Button
ย  ย  $EmailButton.Location = New-Object System.Drawing.Size(540,140)
ย  ย  $EmailButton.Size = New-Object System.Drawing.Size(100,40)
ย  ย  $EmailButton.Text = "Send Email"

ย  ย  #Create the Progress-Bar.
ย  ย  $label1 = New-Object System.Windows.Forms.Label
ย  ย  $label1.Location = New-Object System.Drawing.Size(20,230)ย 
ย  ย  $label1.Size = New-Object System.Drawing.Size(280,20)
ย  ย  $label1.AutoSize = $true
ย  ย  $label1.Text = "Progress..."

ย  ย  $PB = New-Object System.Windows.Forms.ProgressBar
	$PB.Name = "PowerShellProgressBar"
	$PB.Value = 0
	$PB.Style="Continuous"

ย  ย  $System_Drawing_Size = New-Object System.Drawing.Size
	$System_Drawing_Size.Width = 200 - 40
	$System_Drawing_Size.Height = 20
	$PB.Size = $System_Drawing_Size
	$PB.Left = 20
	$PB.Top = 250
ย  ย ย 
ย  ย  #Initiate Snapshot
ย  ย  $HButton.Add_Click(
ย  ย  {ย 
ย  ย  ย  ย  $report= @()
ย  ย  ย  ย  $counter = 0
ย  ย  ย  ย  If ($SR_textBox.TextLength -ne 0 -and $SN_textBox.TextLength -ne 0)
ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  $S_Name= $SR_textBox.text+ " - " +$SN_textBox.textย ย 
ย  ย  ย  ย  }
ย  ย  ย  ย  Else{
ย  ย  ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("SR# or Snapshot Name cannot be blank", "Info")
ย  ย  ย  ย  ย  ย  return
ย  ย  ย  ย  }
	ย  ย 
ย  ย  ย  ย  If ($textbox.TextLength -eq 0)
ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("Server List is empty", "Info")
ย  ย  ย  ย  ย  ย  returnย  ย  ย  ย 
ย  ย  ย  ย  }
ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("Sit back and relax while Snapshot is taken !!!", "VM Snapshot")
ย  ย  ย  ย  $ServerList=$textbox.Text.Split("`n")|%{$_.trim()}
ย  ย  ย  ย  Foreach ($vm in $ServerList)
ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  if($vm -eq "")
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  $counter++
ย  ย  ย  ย  ย  ย  ย  ย  [Int]$Percentage = ($Counter/$ServerList.Count)*100
ย  ย  ย  ย  ย  ย  ย  ย  $PB.Value = $Percentage
ย  ย  ย  ย  ย  ย  ย  ย  continue
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  ย  ย ย 
ย  ย  ย  ย  ย  ย  if ($RadioButton1.Checked -eq $True)ย 
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  Add-PSSnapin VMware.VimAutomation.Core
ย  ย  ย  ย  ย  ย  ย  ย  Connect-VIServer -Server vCenter1
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  if ($RadioButton2.Checked -eq $True)ย 
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  Add-PSSnapin VMware.VimAutomation.Core
ย  ย  ย  ย  ย  ย  ย  ย  Connect-VIServer -Server vCenter2
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  $Exists = get-vm -name $vm -ErrorAction SilentlyContinue
ย  ย  ย  ย  ย  ย  If ($Exists)
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  If ($RadioButton3.Checked -eq $True)
ย  ย  ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  Get-VM $vm |New-snapshot -Name $S_Name -Description $SD_textBox.Text
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  $rep = Get-VM $vm | Get-Snapshot | Select-Object @{Name='VM';Expression={$_.vm}},@{Name='Snapshot_Name';Expression={$_.name}},@{Name='Description';Expression={$_.Description}},@{Name='Created';Expression={$_.Created}},@{Name='Remarks';Expression={""}}
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  $report = $report + $rep
ย  ย  ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  ย  ย  If ($RadioButton4.Checked -eq $True)
ย  ย  ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  Get-VM $vm |New-snapshot -Name $S_Name -Description $SD_textBox.Text -Memory
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  $rep = Get-VM $vm | Get-Snapshot | Select-Object @{Name='VM';Expression={$_.vm}},@{Name='Snapshot_Name';Expression={$_.name}},@{Name='Description';Expression={$_.Description}},@{Name='Created';Expression={$_.Created}},@{Name='Remarks';Expression={""}}
ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  $report = $report + $rep
ย  ย  ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  If (!$Exists)
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  $row= New-Object PSObject -Property @{VM = $vm;Snapshot_Name = "";Description = "";Created = "";Remarks="Server not Found"}
ย  ย  ย  ย  ย  ย  ย  ย  $report += $row
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  $counter++
ย  ย  ย  ย  ย  ย  [Int]$Percentage = ($Counter/$ServerList.Count)*100
ย  ย  ย  ย  ย  ย  $PB.Value = $Percentage
ย  ย  ย  ย  }
ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("Snapshot taken successfully" , "Report Generation")
ย  ย  ย  ย  $report |Select-object @{Name="HOSTNAME"; Expression={$_.VM}},@{Name="Snapshot_Name"; Expression={$_.Snapshot_Name}},@{Name="Description"; Expression={$_.Description}},@{Name="Created: Date &amp; Time"; Expression={$_.Created}},@{Name='Remarks';Expression={$_.Remarks}}| Export-Csv $file -NoTypeInformation
ย  ย  })

ย  ย  #Report Generation
ย  ย  $RButton.Add_Click(
ย  ย  {ย  ย ย 
		ii $path
ย  ย  })

ย  ย  #Send Email
ย  ย  $EmailButton.Add_Click(
ย  ย  {ย  ย 
ย  ย  ย  ย  #Create Label
ย  ย  ย  ย  $ToLabel = New-Object System.Windows.Forms.Label
ย  ย  ย  ย  $ToLabel.Location = New-Object System.Drawing.Size(20,20)ย 
ย  ย  ย  ย  $ToLabel.Size = New-Object System.Drawing.Size(100,20)
ย  ย  ย  ย  $ToLabel.AutoSize = $true
ย  ย  ย  ย  $ToLabelFont = New-Object Drawing.Font("Times New Roman",12,[System.Drawing.FontStyle]::Bold)
ย  ย  ย  ย  $ToLabel.Font = $ToLabelFont
ย  ย  ย  ย  $ToLabel.Text = "*To:"

ย  ย  ย  ย  $CcLabel = New-Object System.Windows.Forms.Label
ย  ย  ย  ย  $CcLabel.Location = New-Object System.Drawing.Size(20,50)ย 
ย  ย  ย  ย  $CcLabel.Size = New-Object System.Drawing.Size(100,20)
ย  ย  ย  ย  $CcLabel.AutoSize = $true
ย  ย  ย  ย  $CcLabelFont = New-Object Drawing.Font("Times New Roman",12,[System.Drawing.FontStyle]::Bold)
ย  ย  ย  ย  $CcLabel.Font = $CcLabelFont
ย  ย  ย  ย  $CcLabel.Text = "Cc: (Optional)"

ย  ย  ย  ย  #Create the TextBox Email Address.
ย  ย  ย  ย  $ToBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  ย  ย  $ToBox.Location = New-Object System.Drawing.Size(140,20)ย 
ย  ย  ย  ย  $ToBox.Size = New-Object System.Drawing.Size(250,20)
ย  ย  ย  ย  $ToBoxFont = New-Object Drawing.Font("Times New Roman",8)
ย  ย  ย  ย  $ToBox.Font=$ToBoxFont
ย  ย  ย  ย  $ToBox.AcceptsReturn = $true
ย  ย  ย  ย  $ToBox.AcceptsTab = $false
ย  ย  ย  ย  #$ToBox.text=""
ย  ย  ย  ย  $ToBox.CharacterCasing='lower'

ย  ย  ย  ย  $CcBox = New-Object System.Windows.Forms.TextBoxย 
ย  ย  ย  ย  $CcBox.Location = New-Object System.Drawing.Size(140,50)ย 
ย  ย  ย  ย  $CcBox.Size = New-Object System.Drawing.Size(250,20)
ย  ย  ย  ย  $CcBoxFont = New-Object Drawing.Font("Times New Roman",8)
ย  ย  ย  ย  $CcBox.Font=$CcBoxFont
ย  ย  ย  ย  $CcBox.AcceptsReturn = $true
ย  ย  ย  ย  $CcBox.AcceptsTab = $false
ย  ย  ย  ย  $CcBox.text=""
ย  ย  ย  ย  $CcBox.CharacterCasing='lower'
ย  ย  ย  ย ย 
ย  ย  ย  ย  #Create Email Send Button
ย  ย  ย  ย  $SendButton = New-Object System.Windows.Forms.Button
ย  ย  ย  ย  $SendButton.Location = New-Object System.Drawing.Size(20,100)
ย  ย  ย  ย  $SendButton.Size = New-Object System.Drawing.Size(100,40)
ย  ย  ย  ย  $ButtonFont = New-Object Drawing.Font("Times New Roman",8,[System.Drawing.FontStyle]::Bold)
ย  ย  ย  ย  $SendButton.Font=$ButtonFont
ย  ย  ย  ย  $SendButton.Text = "Send Email"

ย  ย  ย  ย  $CancelButton = New-Object System.Windows.Forms.Button
ย  ย  ย  ย  $CancelButton.Location = New-Object System.Drawing.Size(150,100)
ย  ย  ย  ย  $CancelButton.Size = New-Object System.Drawing.Size(100,40)
ย  ย  ย  ย  $CancelButton.Font=$ButtonFont
ย  ย  ย  ย  $CancelButton.Text = "Cancel"

ย  ย  ย  ย  $Emailform.Controls.Add($ToLabel)
ย  ย  ย  ย  $Emailform.Controls.Add($CcLabel)
ย  ย  ย  ย  $Emailform.Controls.Add($ToBox)
ย  ย  ย  ย  $Emailform.Controls.Add($CCBox)
ย  ย  ย  ย  $Emailform.Controls.Add($SendButton)
ย  ย  ย  ย  $Emailform.Controls.Add($CancelButton)
ย  ย  ย  ย ย 
ย  ย  ย  ย  $SendButton.Add_Click(
ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  If ($ToBox.Text.Length -eq 0)
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("Email address cannot be empty" , "Email Info")
ย  ย  ย  ย  ย  ย  ย  ย  return
ย  ย  ย  ย  ย  ย  }
ย  ย  ย  ย  ย  ย  #---------------------------------------------------------------------
ย  ย  ย  ย  ย  ย  # Generate the HTML report and output to file
ย  ย  ย  ย  ย  ย  #---------------------------------------------------------------------

ย  ย  ย  ย  ย  ย  $head = "&lt;style>"
ย  ย  ย  ย  ย  ย  $head = $head + "BODY{background-color:white;}"
ย  ย  ย  ย  ย  ย  $head = $head + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
ย  ย  ย  ย  ย  ย  $head = $head + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#778899}"
ย  ย  ย  ย  ย  ย  $head = $head + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black}"
ย  ย  ย  ย  ย  ย  $head = $head + "&lt;/style>"

ย  ย  ย  ย  ย  ย  # SMTP info
ย  ย  ย  ย  ย  ย  $Toemail=$ToBox.Text
ย  ย  ย  ย  ย  ย  $strTo=$Toemail
ย  ย  ย  ย  ย  ย  $strCc=$CCBox.Text
ย  ย  ย  ย  ย  ย  $strSubject = "Snapshot Taken : $S_Name"
ย  ย  ย  ย  ย  ย  $StrMsg="Hi All, &lt;br>Snapshot has been taken successfully for below list of servers &lt;br>&lt;br>"
ย  ย  ย  ย  ย  ย  $strBody = "Attached is the list of Snapshots"
ย  ย  ย  ย  ย  ย  $strMail = $strmsg

ย  ย  ย  ย  ย  ย  # Write the output to an HTML file
ย  ย  ย  ย  ย  ย  $strOutFile = $Path+"email.html"
ย  ย  ย  ย  ย  ย  $ComputerName=(Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
ย  ย  ย  ย  ย  ย  Get-Content -Path $File |ConvertFrom-CSV | ConvertTo-HTMLย  -Head $head -Body $StrMsg | Out-File $StrOutFile
ย  ย  ย  ย  ย  ย ย 
	ย  ย  ย  ย  # Mail the output file
	ย  ย  ย  ย  $msg = new-object Net.Mail.MailMessage
	ย  ย  ย  ย  $att = new-object Net.Mail.Attachment($File)
	ย  ย  ย  ย  $smtp = new-object Net.Mail.SmtpClient("SMTP Server")
ย  ย  ย  ย  ย  ย  $msg.From ="From@domain.com"
	ย  ย  ย  ย  $msg.To.Add($strTo)
ย  ย  ย  ย  ย  ย  If ($strCc.Length -ne 0)
ย  ย  ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  ย  ย  $msg.cc.Add($strcc)
ย  ย  ย  ย  ย  ย  }
	ย  ย  ย  ย  $msg.Subject = $strSubject
	ย  ย  ย  ย  $msg.IsBodyHtml = 1
	ย  ย  ย  ย  $msg.Body = Get-Content $strOutFile
	ย  ย  ย  ย  $msg.Attachments.Add($att)
ย  ย  ย  ย  ย  ย  $smtp.Send($msg)
ย  ย  ย  ย  ย  ย  ย  ย  [System.Windows.Forms.MessageBox]::Show("Email Send !!!","Info")
ย  ย  ย  ย  ย  ย  ย  ย  $Emailform.close()
ย  ย  ย  ย  })
ย  ย  ย  ย  $CancelButton.Add_Click(
ย  ย  ย  ย  {
ย  ย  ย  ย  ย  ย  $Emailform.close()
ย  ย  ย  ย  })
ย  ย  ย  ย  $Emailform.Add_Shown({$Emailform.Activate()})
ย  ย  ย  ย  $Emailform.ShowDialog() > $nullย 
ย  ย  ย  ย  ย  ย  ย  ย 
ย  ย  })
ย  ย  ย  ย ย 
ย  ย  # Add all of the controls to the form.
ย  ย  $form.Controls.Add($label)
ย  ย  $form.Controls.Add($textBox)
ย  ย  $form.Controls.Add($groupBox)
ย  ย  $form.Controls.Add($groupBox1)
ย  ย  $form.Controls.Add($RButton)
ย  ย  $form.Controls.Add($HButton)
ย  ย  $form.Controls.Add($label1)
ย  ย  $form.Controls.Add($SR_label)
ย  ย  $form.Controls.Add($SR_textBox)
ย  ย  $form.Controls.Add($SN_label)
ย  ย  $form.Controls.Add($SN_textBox)
ย  ย  $form.Controls.Add($SD_label)
ย  ย  $form.Controls.Add($SD_textBox)
ย  ย  $form.Controls.Add($PB)
ย  ย  $form.Controls.Add($EmailButton)
ย  ย  # Initialize and show the form.
ย  ย  $form.Add_Shown({$form.Activate()})
ย  ย  $form.ShowDialog() > $null
}
Set-ExecutionPolicy unrestricted -Force
$date=get-Date -format "ddMMyy_HHmm"
$ComputerName=(Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
$Path=[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop)+"\Report\"
If ((Test-Path $Path) -eq $false)
{
ย  ย  New-Item $Path -type directory
}
New-Item -ErrorAction Ignore -ItemType directory -Path Report
$File=$Path + "SnapshotReport_$date.csv"
Snapshot</pre>
<!-- /wp:syntaxhighlighter/code -->

๐Ÿ’ก Why this is a “Lazy” Win:

  1. Tab Isolation: You won’t accidentally delete snapshots while trying to create them.
  2. RunAsync Switch: I added -RunAsync to the deletion. This means the GUI won’t “freeze” while vCenter is doing the heavy lifting of disk consolidation.
  3. Standardized Cleanup: By hardcoding $Days = 2, you ensure that your team follows a consistent 48-hour retention policy.

Exporting PSTs and Setting Up External Forwarding | LazyAdminBlog.com

Posted on Updated on

As a “Lazy Admin,” I like to keep my cheat sheets handy so I donโ€™t have to look up the same syntax every time a request comes in. Todayโ€™s snippets cover exporting mailboxes to PST and the “correct” way to forward mail to an external address.

1. Exporting Mailboxes to PST

Whether you are decommissioning a user or just taking a backup, New-MailboxExportRequest is your best friend.

Note: Ensure your Exchange Trusted Subsystem has read/write permissions on the network share before running these.

Export a Standard Mailbox:

New-MailboxExportRequest -Mailbox "Mailbox Name" -FilePath \\Sharelocation\Export.pst -DomainController DC_FQDN

Export a Mailbox Archive:

If the user has an In-Place Archive enabled, use the -IsArchive switch:

New-MailboxExportRequest -Mailbox "Mailbox Name" -IsArchive -FilePath \\Sharelocation\Archive.pst -DomainController DC_FQDN

2. Reconnecting a Disconnected Mailbox

If you have a disconnected mailbox that needs to be linked to a user account:

Connect-Mailbox -Identity "Mailbox Name" -Database DBName -User "UserName"

3. Forwarding Mail Externally (The Right Way)

To forward mail to an external address (like a Gmail or Outlook account), you shouldn’t just type an address into a transport rule. The cleanest way is to create a Mail Contact.

Step A: Create the Contact

  1. Login to Exchange Admin Center > Recipients > Contacts.
  2. Click Add > Mail Contact.
  3. Give it a sensible name.

Pro Tip: If you don’t want this contact cluttering up your Global Address List (GAL), hide it with PowerShell:

Set-MailContact "ALIAS-NAME" -HiddenFromAddressListsEnabled $true

Step B: Enable Forwarding via GUI

  1. Go to Recipients > Mailboxes.
  2. Locate the user you want to forward from and click Edit.
  3. Go to Mailbox Features > Scroll down to Mail Flow > View Details.
  4. Check Enable Forwarding.
  5. Browse and select the Contact you created in Step A.
  6. Optional: Check “Deliver message to both forwarding address and mailbox” if you want a copy kept in the original inbox.

Step C: Enable Forwarding via PowerShell (The Lazy Way)

If you don’t want to click through the GUI, just run this:

Set-Mailbox -Identity "Internal User" -ForwardingAddress "ExternalContactAlias" -DeliverToMailboxAndForward $true

The “Source of Truth” Audit: Finding Missing Assets in ServiceNow | LazyAdminBlog.com

Posted on Updated on

How to catch the servers that escaped your CMDB using PowerShell.

Every admin knows the struggle: Your discovery tool (Soda) says you have 500 servers, but your CMDB (ServiceNow) only shows 480. Those missing 20 servers are usually the ones that cause the most trouble because nobody is monitoring them or tracking their lifecycles.

Instead of manual VLOOKUP hell in Excel, we can use the “Lazy Admin” way: Compare-Object.

The Logic: Why Compare-Object is King

The heart of this script is the -Property AssetName and the SideIndicator -EQ "<=".

  • <= means the asset exists in the first list (Soda) but is missing from the second (ServiceNow).
  • This allows you to pinpoint exactly what needs to be imported or investigated in your CMDB.

The Script: CMDB Gap Analysis

PowerShell
# 1. Load your data sources
# Place the Soda List of servers
$SodaServers = Import-Csv "C:\Temp\SODAServerAssets.csv"
# Place the ServiceNow List of servers
$SNServers = Import-Csv "C:\Temp\SNServersMissing.csv"
# 2. Define the output
$FileLocation = "C:\temp\ServerMissing.csv"
# 3. Compare the two lists based on the AssetName property
# We use "<=" to find items that exist in Soda but NOT in ServiceNow
$MissingServers = Compare-Object $SodaServers $SNServers -Property AssetName | Where-Object {$_.SideIndicator -eq "<="}
# 4. Map the results back to the original Soda data to keep all columns (IP, OS, Owner, etc.)
$DiffServers = @()
foreach ($missedServer in $MissingServers) {
$DiffServers += $SodaServers | Where-Object {$_.AssetName -eq $missedServer.AssetName}
}
# 5. Export the "Clean" list for your next ServiceNow Import
$DiffServers | Export-Csv $FileLocation -NoClobber -NoTypeInformation
Write-Host "Audit Complete! Missing servers exported to $FileLocation" -ForegroundColor Green

๐Ÿ› ๏ธ Lazy Admin Tips for this Script:

  1. Column Headers: Ensure both CSV files have a column named exactly AssetName. If one is called Name and the other HostName, the script will fail.
  2. The “Full Export” Trick: By using the foreach loop at the end, we aren’t just getting a list of names; we are pulling the entire row from the Soda CSV. This gives you all the metadata (IPs, serial numbers) you need to actually fix the record in ServiceNow.
  3. Automate it: If you can get an API or an automated export from Soda and ServiceNow, you can run this as a scheduled task every Friday afternoon.

The Bulk-Replace Macro & Decoding the SID Matrix | LazyAdminBlog.com

Posted on Updated on

Why manually edit 1,000 rows when a 10-line script can do it for you?

As an admin, you’re constantly dealing with data. Sometimes itโ€™s a list of server names in Excel that need updating, and other times itโ€™s a cryptic string of numbers in a security log. Today, weโ€™re tackling both.


1. Excel Bulk-Replace: The “Set and Forget” Macro

Weโ€™ve all been there: You have a list of old server names and a list of new ones. Running Ctrl+H fifty times is not the “Lazy Admin” way. Instead, use this VBA macro to map an entire range of changes in one go.

How to use it:

  1. Open your Excel sheet and hit Alt + F11 to open the VBA Editor.
  2. Go to Insert > Module and paste the code below.
  3. Hit F5 to run.
  4. Select the Original Range: The data you want to change.
  5. Select the Replace Range: A two-column list where Column A is the “Find” and Column B is the “Replace.”
VBScript
Sub MultiFindNReplace()
' The Lazy Admin's Bulk Tool
Dim Rng As Range
Dim InputRng As Range, ReplaceRng As Range
xTitleId = "LazyAdminReplace"
Set InputRng = Application.Selection
Set InputRng = Application.InputBox("Range to search in:", xTitleId, InputRng.Address, Type:=8)
Set ReplaceRng = Application.InputBox("Mapping Range (Col A: Old, Col B: New):", xTitleId, Type:=8)
Application.ScreenUpdating = False
For Each Rng In ReplaceRng.Columns(1).Cells
InputRng.Replace what:=Rng.Value, replacement:=Rng.Offset(0, 1).Value, Lookat:=xlWhole
Next
Application.ScreenUpdating = True
End Sub

2. Decoding the SID: Who is ‘S-1-5-21…’?

When you see a SID (Security Identifier) in a log, itโ€™s not just a random string. Itโ€™s a structured ID that tells you exactly where that user came from.

The Anatomy of a SID:

  • S: Identifies this as a SID.
  • 1: The revision number (still at revision 1).
  • 5: The Identifier Authority. ‘5’ means NT Authority (Standard Windows accounts).
  • 21: Specifies that the following sub-authorities identify a Domain or Local Machine.
  • 1000+: The RID (Relative Identifier). Any user-created object starts at 1000. 500 is always the built-in Administrator.

Quick Lookup Commands:

Need to find the name behind a SID right now? Use these:

Command Prompt (WMIC):

VBScript
wmic useraccount where sid='S-1-5-21-xxxx' get name

PowerShell (AD Module):

VBScript
Get-ADGroup -Identity S-1-5-32-544

(This specific one is the local Administrators group!)


๐Ÿ›ก๏ธ Lazy Admin Verdict:

Keep a “Mapping Table” in a separate Excel tab for all your bulk naming changes. Use the macro to apply them to your master inventory. For SIDs, memorize the “5-21” partโ€”itโ€™s the most common string youโ€™ll see in enterprise environments.

Azure Alert: Default Outbound Access Ends March 31st 2026 | LazyAdminBlog.com

Posted on Updated on

Is your “Internet-less” VM about to lose its connection? Here is the fix.

For years, Azure allowed Virtual Machines without an explicit outbound connection (like a Public IP or NAT Gateway) to “cheat” and access the internet using a default, hidden IP. That ends on March 31st 2026. If you haven’t transitioned your architecture, your updates will fail, your scripts will break, and your apps will go dark.

1. What exactly is changing?

Microsoft is moving toward a “Secure by Default” model. The “Default Outbound Access” (which was essentially a random IP assigned by Azure) is being retired. From now on, you must explicitly define how a VM talks to the outside world.

2. The Three “Lazy Admin” Solutions

You have three ways to fix this before the deadline. Choose the one that fits your budget and security needs:

Option A: The NAT Gateway (Recommended)

This is the most scalable way. You associate a NAT Gateway with your Subnet. All VMs in that subnet will share one (or more) static Public IPs for outbound traffic.

  • Pro: Extremely reliable and handles thousands of concurrent sessions.
  • Con: There is a small hourly cost + data processing fee.

Option B: Assign a Public IP to the VM

The simplest “Quick Fix.” Give the VM its own Standard Public IP.

  • Pro: Immediate fix for a single server.
  • Con: Itโ€™s a security risk (opens a door into the VM) and gets expensive if you have 50 VMs.

Option C: Use a Load Balancer

If you already use an Azure Load Balancer, you can configure Outbound Rules.

  • Pro: Professional, enterprise-grade setup.
  • Con: More complex to configure if you’ve never done it before.

3. How to find your “At Risk” VMs

Don’t wait for March 31st 2026 to find out what’s broken. Run this PowerShell snippet to find VMs that might be relying on default outbound access:

# Find VMs without a Public IP in a specific Resource Group
$VMs = Get-AzVM -ResourceGroupName "YourRGName"
foreach ($vm in $VMs) {
$nic = Get-AzNetworkInterface -ResourceId $vm.NetworkProfile.NetworkInterfaces[0].Id
if ($null -eq $nic.IpConfigurations.PublicIpAddress) {
Write-Host "Warning: $($vm.Name) has no Public IP and may rely on Default Outbound Access!" -ForegroundColor Yellow
}
}

๐Ÿ›ก๏ธ Lazy Admin Verdict:

If you have more than 3 VMs, deploy a NAT Gateway. Itโ€™s the “Set and Forget” solution that ensures you won’t get a 2 AM call on April 1st when your servers can’t reach Windows Update.

M365 E7: The “Super SKU” is Here (And it Costs $99) | LazyAdminBlog.com

Posted on Updated on

Is the new ‘Frontier Suite’ a lazy admin’s dream or a budget nightmare?

After 11 years of E5 being the king of the mountain, Microsoft has officially announced its successor: Microsoft 365 E7. Launching May 1, 2026, this isn’t just a minor updateโ€”itโ€™s a $99/month powerhouse designed for an era where AI agents are treated like actual employees.

1. Whatโ€™s inside the E7 Box?

If youโ€™ve been “nickel and dimed” by add-on licenses for the last two years, E7 is Microsoftโ€™s way of saying “Fine, hereโ€™s everything.”

  • Microsoft 365 Copilot (Wave 3): No more $30 add-on. Itโ€™s baked in, including the new “Coworker” mode developed with Anthropic.
  • Agent 365: This is the big one. A brand-new control plane to manage, secure, and govern AI agents across your tenant.
  • Microsoft Entra Suite: You get the full identity stack, including Private Access (ZTNA) and Internet Access (SSE), which were previously separate costs.
  • Advanced Security: Enhanced features for Defender, Intune, and Purview specifically tuned for “Agentic AI” (AI that actually performs tasks, not just answers questions).

2. The $99 Math: Is it worth it?

At first glance, $99 per user per month sounds like a typo. But letโ€™s look at the “Lazy Admin” math:

ComponentStandalone Cost (Est.)
M365 E5$60 (post-July 2026 hike)
M365 Copilot$30
Agent 365$15
Entra Suite Add-on$12
Total Value$117/month

By moving to E7, youโ€™re saving about $18 per user and, more importantly, you stop managing four different license renewals. That is the definition of working smarter.

3. The “Agentic” Shift

Why do we need E7? Because in 2026, agents are becoming “Frontier Workers.” Microsoftโ€™s new stance is that AI agents need their own identities. Under E7, your automated agents get their own Entra ID, mailbox, and Teams access so they can attend meetings and file reports just like a human. E7 provides the governance layer to make sure these agents don’t go rogue and start emailing your CEO the companyโ€™s secrets.


๐Ÿ“Š Microsoft 365 License Comparison: E3 vs. E5 vs. E7

Feature CategoryM365 E3M365 E5M365 E7 (Frontier)
Monthly Cost~$36.00~$57.00$99.00
Core ProductivityFull Apps + TeamsFull Apps + TeamsFull Apps + Teams
SecurityBasic (Entra ID P1)Advanced (Entra ID P2)Autonomous (P3)
ComplianceCore eDiscoveryInner Risk + PrivaAgentic Governance
AI IntegrationAdd-on RequiredAdd-on RequiredNative Copilot Wave 3
Specialized ToolingNonePower BI ProAgent 365 (Suite)
Threat ProtectionDefender for EndpointDefender XDR FullQuantum Defender
Endpoint MgmtIntune (Basic)Intune (Plan 2)Autopilot Frontie

๐Ÿ›ก๏ธ Lazy Admin Verdict:

  • Upgrade to E7 if: You already have 50%+ Copilot adoption and youโ€™re starting to build custom AI agents in Copilot Studio.
  • Stay on E5 if: Youโ€™re still fighting with users to turn on MFA and haven’t touched AI yet.

๐Ÿ“š References & Further Reading

Guide to the Entra ID Passkey Rollout (March 2026) | LazyAdminBlog.com

Posted on Updated on

How to avoid 500 helpdesk tickets by spending 10 minutes in the Admin Center today.

If you woke up this morning to find a new “Default Passkey Profile” in your Entra tenant, don’t panic. Microsoft is officially “encouraging” (read: forcing) the world toward phishing-resistant auth. As a Lazy Admin, your goal isn’t to fight the changeโ€”it’s to control it so it doesn’t control your weekend.

1. The Big Change: Passkey Profiles

Previously, FIDO2 was a simple “On/Off” switch. Now, we have Passkey Profiles.

  • The Default Behavior: If you didn’t opt-in, Microsoft has created a “Default Profile” for you.
  • The Trap: If you had “Enforce Attestation” set to No, Microsoft is now allowing Synced Passkeys (iCloud Keychain, Google Password Manager). This means users can put corporate credentials on their personal iPhones.

2. The “Lazy” Strategy: Tiered Security

Don’t treat your CEO and your Summer Intern the same way. Use the new Group-Based Profiles to save yourself the headache of “One Size Fits None.”

User GroupRecommended ProfileWhy?
IT AdminsDevice-Bound OnlyRequires a physical YubiKey or Windows Hello. No syncing to the cloud.
Standard UsersSynced & Device-BoundMaximum convenience. If they lose their phone, iCloud/Google restores the key. Zero helpdesk calls.
ContractorsAAGUID RestrictedOnly allow specific hardware models youโ€™ve issued to them.

3. Avoid the “Registration Deadlock”

Many admins are seeing “Helpdesk Hell” because their Conditional Access (CA) policies are too strict.

The Problem: You have a policy requiring “Phishing-Resistant MFA” to access “All Apps.” A user tries to register a passkey, but they can’t log in to the registration page because… they don’t have a passkey yet.

The Lazy Fix: Exclude the “Register security information” user action from your strictest CA policies, or better yet, issue a Temporary Access Pass (TAP) for 24 hours. A TAP satisfies the MFA requirement and lets them onboard themselves without calling you.


๐Ÿ› ๏ธ The 5-Minute “Lazy Admin” Checklist

  1. [ ] Check your Attestation: Go to Security > Authentication Methods > Passkey (FIDO2). If you want to block personal iPhones, set Enforce Attestation to Yes.
  2. [ ] Kill the Nudges: If you aren’t ready for the rollout, disable the “Microsoft-managed” registration campaigns before they start bugging your users on Monday.
  3. [ ] Review AAGUIDs: If you only use YubiKeys, make sure their AAGUIDs are explicitly whitelisted in your Admin profile.

Bottom Line: Spend 10 minutes setting up your profiles today, or spend 10 hours resetting MFA sessions next week. Choose wisely.

Setting Up Microsoft Entra Connect (Step-by-Step) | LazyAdminBlog.com

Posted on Updated on

Why do manual user management when you can let a sync engine do the heavy lifting?

If youโ€™re still manually creating users in both on-premises Active Directory and the Microsoft 365 portal, stop. Youโ€™re working too hard. Microsoft Entra Connect (formerly Azure AD Connect) is the “bridge” that syncs your local identities to the cloud. Set it up once, and your users get one identity for everything.

1. The “Pre-Flight” Checklist (Don’t skip this!)

The biggest mistake admins make is running the installer before the environment is ready. To be truly “lazy,” do the prep work so the installation doesn’t fail midway.

  • Server: A domain-joined Windows Server 2016 or later (2022 is recommended).
  • Hardware: Minimum 4GB RAM and a 70GB hard drive.
  • Permissions: * Local: You need to be a Local Admin on the sync server.
    • On-Prem: An Enterprise Admin account for the initial setup.
    • Cloud: A Global Administrator or Hybrid Identity Administrator account in Entra ID.
  • Software: .NET Framework 4.7.2 or higher and TLS 1.2 enabled.

Pro Tip: Run the Microsoft IdFix tool first. It finds duplicate emails and weird characters in your AD that would otherwise break the sync.


2. Step-by-Step Installation

Download the latest version of the Entra Connect MSI here.

Step A: The Express Route

  1. Launch AzureADConnect.msi.
  2. Agree to the terms and click Use Express Settings. (Note: Use “Custom” only if you have multiple forests or need specific attribute filtering).
  3. Connect to Entra ID: Enter your Cloud Admin credentials.
  4. Connect to AD DS: Enter your Enterprise Admin credentials.
  5. Entra ID Sign-in: Ensure your UPN suffixes match. If your local domain is corp.local but your email is lazyadminblog.com, you need to add lazyadminblog.com as a UPN suffix in AD.

Step B: The “Staging Mode” Safety Net

Before you hit install, youโ€™ll see a checkbox for “Start the synchronization process when configuration completes.” If you are replacing an old server or are nervous about what will happen to your 5,000 users, check the “Enable staging mode” box. This allows the server to calculate the sync results without actually exporting anything to the cloud. You can “peek” at the results before going live.


3. Post-Setup: The “Lazy” Health Check

Once installed, the sync runs every 30 minutes by default. You don’t need to babysit it, but you should know how to check it:

  • The Desktop Tool: Open the Synchronization Service Manager to see a green “Success” status for every run.
  • The PowerShell Way: To force a sync right now (because youโ€™re too impatient for the 30-minute window), run:PowerShellStart-ADSyncSyncCycle -PolicyType Delta

4. Troubleshooting Common “Gotchas”

  • “Top-level domain not verified”: You forgot to add your domain (e.g., https://www.google.com/search?q=myblog.com) to the Entra ID portal.
  • “Object Synchronization Triggered Deletion”: By default, Entra Connect won’t delete more than 500 objects at once. This is a safety feature to stop you from accidentally wiping your cloud directory. If you intended to delete them, you’ll need to disable the export deletion threshold.

The “Lazy Admin” Sync Monitor Script

Copy and save this as Monitor-EntraSync.ps1 on your sync server.

# --- CONFIGURATION ---
$SMTPServer = "smtp.yourrelay.com"
$From = "EntraAlert@lazyadminblog.com"
$To = "you@yourcompany.com"
$Subject = "โš ๏ธ ALERT: Entra ID Sync Failure on $(hostname)"
# --- THE LOGIC ---
# Import the AdSync module (usually already loaded on the server)
Import-Module ADSync
# Get the statistics of the very last sync run
$LastRun = Get-ADSyncRunProfileResult | Sort-Object StartDateTime -Descending | Select-Object -First 1
# Check if the result was NOT 'success'
if ($LastRun.Result -ne "success") {
    $Body = @"
    The last Entra ID Sync cycle failed!
    
    Server: $(hostname)
    Run Profile: $($LastRun.RunProfileName)
    End Time: $($LastRun.EndDateTime)
    Result: $($LastRun.Result)
    
    Please log in to the Synchronization Service Manager to investigate.
"@
    # Send the alert
    Send-MailMessage -SmtpServer $SMTPServer -From $From -To $To -Subject $Subject -Body $Body -Priority High
}

๐Ÿ› ๏ธ How to set it up (The Lazy Way)

To make this fully automated, follow these steps:

  1. Create a Scheduled Task: Open Task Scheduler on your Entra Connect server.
  2. Trigger: Set it to run every hour (or every 30 minutes to match your sync cycle).
  3. Action: * Program/script:powershell.exe
    • Add arguments: -ExecutionPolicy Bypass -File "C:\Scripts\Monitor-EntraSync.ps1"
  4. Security Options: Run it as SYSTEM or a Service Account that has local admin rights so it can access the ADSync module.

Why this is better than “Default” monitoring:

  • No Noise: You only get an email if there is an actual problem.
  • Proactive: You’ll likely know the sync is broken before your users start complaining that their new passwords aren’t working.
  • Zero Cost: No need for expensive third-party monitoring tools for a single-server task.

References & Further Reading

EVC Mode & CPU Compatibility FAQ | LazyAdminBlog.com

Posted on Updated on

Youโ€™ve just unboxed a shiny new host with the latest Intel or AMD processor, but your current cluster is running hardware from three years ago. You try to vMotion a VM, and vSphere gives you the dreaded “CPU Incompatibility” error.

Enter Enhanced vMotion Compatibility (EVC). Hereโ€™s everything you need to know to get your mixed-hardware cluster working without the headache.


What exactly is EVC?

Think of EVC as a “lowest common denominator” filter for your CPUs. It masks the advanced features of newer processors so that every host in the cluster appears to have the exact same instruction set. This allows VMs to live-migrate between old and new hardware because the “view” of the CPU never changes.

Quick FAQ

Q: Can I mix Intel and AMD in the same EVC cluster? A: No. EVC only works within a single vendor family. You can mix different generations of Intel, or different generations of AMD, but you cannot vMotion between the two brands.

Q: Will EVC slow down my new servers? A: Technically, yesโ€”but rarely in a way youโ€™ll notice. It hides new instructions (like specialized encryption or AI math sets), but the raw clock speed and core count of your new CPUs are still fully utilized. Most general-purpose VMs don’t use the high-end instructions being masked.

Q: Do I need to power off VMs to enable EVC? A: It depends:

  • Enabling on an empty cluster: No downtime.
  • Enabling on a cluster where VMs are already running on the oldest host: Usually no downtime.
  • Enabling on a cluster where VMs are running on newer hosts: You must power off those VMs so they can “re-boot” with the masked CPU instructions.

Q: What is “Per-VM EVC”? A: Introduced in vSphere 6.7, this allows you to set the EVC mode on the VM itself rather than the whole cluster. This is a lifesaver for migrating VMs across different vCenters or into the Cloud (like AWS/Azure).


How to Find Your Correct EVC Mode

Don’t guess. Use the official tool:

  1. Go to the VMware Compatibility Guide (CPU/EVC Matrix).
  2. Select your ESXi version.
  3. Select the CPU models of your oldest and newest hosts.
  4. The tool will tell you the highest supported “Baseline” you can use.

Step-by-Step: Enabling EVC on an Existing Cluster

  1. Select your Cluster in vCenter.
  2. Go to Configure > VMware EVC.
  3. Click Edit.
  4. Select Enable EVC for Intel/AMD hosts.
  5. Choose the Baseline that matches your oldest host.
  6. Validation: vCenter will check if any running VMs are currently using features above that baseline. If they are, you’ll need to shut them down before you can save the settings.

Summary Table: EVC Baselines

If your oldest host is…Use this EVC Mode
Intel Ice LakeIntel “Ice Lake” Generation
Intel Cascade LakeIntel “Cascade Lake” Generation
AMD EPYC RomeAMD EPYC “Rome” Generation

Zerto vs. vSphere Replication: Which DR Strategy is for You? | LazyAdminBlog.com

Posted on Updated on

When it comes to Disaster Recovery (DR) in a VMware environment, there are two names that always come up: vSphere Replication (VR) and Zerto.

One is often “free” (included in most licenses), while the other is a premium enterprise powerhouse. But in 2026, with the shifts in Broadcomโ€™s licensing and the rise of ransomware, the choice isn’t just about priceโ€”it’s about how much data you can afford to lose.


The Contenders

1. vSphere Replication (The Built-in Basic)

vSphere Replication is a hypervisor-based, asynchronous replication engine. Itโ€™s integrated directly into vCenter and captures changed blocks to send to a target site.

  • Best For: Small to medium businesses with “relaxed” recovery goals.
  • Cost: Included with vSphere Standard and vSphere Foundation subscriptions.

2. Zerto (The Gold Standard for CDP)

Zerto uses Continuous Data Protection (CDP). Instead of taking snapshots, it uses a lightweight agent on each host to intercept every write in real-time and stream it to the DR site.

  • Best For: Mission-critical apps where losing 15 minutes of data is a catastrophe.
  • Cost: Licensed per VM (Premium pricing).

Key Comparison: RPO and RTO

In the world of “Lazy Adminning,” we care most about RPO (Recovery Point Objective – how much data we lose) and RTO (Recovery Time Objective – how fast we get back up).

FeaturevSphere ReplicationZerto (HPE)
Replication MethodSnapshot-based (Asynchronous)Journal-based (CDP)
Best RPO5 to 15 Minutes5 to 10 Seconds
Point-in-Time RecoveryLimited (up to 24 instances)Granular (Any second within 30 days)
OrchestrationRequires VMware Site Recovery Manager (SRM)Built-in (One-click failover)
SnapshotsUses VM Snapshots (can impact performance)No Snapshots (Zero impact on IOPS)

Why Choose vSphere Replication?

If you have a limited budget and your management is okay with losing 30 minutes of data, VR is the way to go.

  • Pros: Itโ€™s already there. No extra software to install besides the appliance. It works well for low-change workloads.
  • Cons: It relies on snapshots, which can cause “stun” on high-load SQL servers. Without adding SRM (Site Recovery Manager), failover is a manual, painful process of registering VMs and fixing IPs.

Why Choose Zerto?

If you are running a 24/7 shop or protecting against Ransomware, Zerto is king.

  • Pros: The Journal is a time machine. If ransomware hits at 10:05:30 AM, you can failover to 10:05:25 AM. It also handles IP re-addressing and boot ordering natively.
  • Cons: Itโ€™s an expensive add-on. It also requires a “Virtual Replication Appliance” (VRA) on every host in your cluster, which uses a bit of RAM and CPU.

The Verdict: Which one is “Lazy”?

  • vSphere Replication is lazy at the start (easy to turn on), but high-effort during an actual disaster (lots of manual work).
  • Zerto is a bit more work to set up but is the ultimate “Lazy Admin” tool during a disasterโ€”you literally click one button, walk away, and grab a coffee while the entire data center boots itself at the DR site.

Lost Your VM? How to Find Its ESXi Host from the Guest OS | LazyAdminBlog.com

Posted on Updated on

Itโ€™s a classic “Ghost in the Machine” scenario: You can RDP or SSH into a virtual machine, but you can’t find it in vCenter. Maybe itโ€™s a massive environment with thousands of VMs, maybe the naming convention doesn’t match, or maybe you’re dealing with a rogue host that isn’t even in your main cluster.

If VMware Tools is installed and running, the VM actually knows exactly where it lives. You just have to ask it nicely through the Command Prompt.


The Magic Tool: vmtoolsd.exe

On Windows VMs, the VMware Tools service includes a CLI utility called vmtoolsd.exe. This tool can query the hypervisor for specific environment variables that are passed down to the guest.

1. Find the ESXi Hostname

If you need to know which physical server is currently crunching the cycles for your VM, run this command:

Shell
"C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.hypervisor.hostname"

2. Get the ESXi Build Details

Need to know if the underlying host is patched or running an ancient version of ESXi? Query the build number:

Shell
"C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.hypervisor.build"

Why is this useful?

  • vCenter Search is failing: Sometimes the inventory search index gets corrupted, and “Name contains” returns nothing.
  • Nested Environments: If you are running VMs inside VMs, this helps you verify which layer of the onion you are currently on.
  • Troubleshooting Performance: If a VM is lagging, you can quickly identify the host to check for hardware alerts or CPU contention without leaving the OS.

What if I’m on Linux?

The same logic applies! Most modern Linux distributions use open-vm-tools. You can run the same query via the terminal:

Shell
vmtoolsd --cmd "info-get guestinfo.hypervisor.hostname"

Important Requirement: Guest RPC

For these commands to work, the VM must have VMware Tools installed and the guestinfo variables must be accessible. In some hardened environments, admins might disable these RPC (Remote Procedure Call) queries in the .vmx file for security reasons, but in 95% of standard builds, this will work out of the box.

How to Force Cancel a Hung Task in vCenter or ESXi | LazyAdminBlog.com

Posted on Updated on

Weโ€™ve all been there: a vMotion hits 99% and just… stays there. Or a backup job finishes on the proxy side, but vCenter still thinks the VM is “busy.” Usually, the Cancel button is grayed out, leaving you stuck in management limbo.

When the GUI fails you, itโ€™s time to hop into the CLI. Here is how to manually kill a hung task by targeting the VM’s parent process.


Step 1: Verify the Task

Before pulling the trigger, confirm the task is actually stuck and not just slow. Check the Monitor > Tasks and Events tab for the specific VM. If the progress bar hasn’t budged in an hour and the “Cancel” option is disabled, proceed to the host.

Step 2: Enable and Connect via SSH

To kill a process, you need to be on the specific ESXi host where the VM is currently registered.

  1. Enable SSH: Go to the ESXi host in vSphere > Configure > System > Services > Start SSH.
  2. Connect: Open your terminal (Putty, CMD, or Terminal) and log in as root.

Step 3: Locate the Parent Process ID (PID)

We need to find the specific process tied to your VM. Use the ps command combined with grep to filter for your VM’s name.

Run the following command:

Shell
ps -v | grep "Your_VM_Name"

(Note: Using the -v flag in ESXi provides a more detailed view of the world ID and parent processes.)

Look for the line representing the VM’s main process. You are looking for the Leader ID or the first ID listed in the row.

Step 4: Kill the Process

Once you have identified the ID (e.g., 859467), send the kill signal. Start with a standard terminate signal, which allows the process to clean up after itself.

Run the command:

Shell
kill 859467

Lazy Admin Tip: If the process is extremely stubborn and won’t die, you can use kill -9 859467 to force an immediate termination. Use this as a last resort!

Step 5: Verify in vSphere

Give vCenter a minute to catch up. The hung task should now disappear or show as “Canceled” in the Tasks and Events console. Your VM should return to an “Idle” state, allowing you to power it on, move it, or restart your backup.

The Robocopy Masterclass: Faster Migrations with Multi-Threading | LazyAdminBlog.com

Posted on Updated on

Why use File Explorer when you can use a 128-thread engine?

If you are still using “Drag and Drop” to move terabytes of data, stop. Not only is it slow, but if the network blips for half a second, the whole process fails. Robocopy is built to survive network hiccups and, since Windows 7, it has a “Turbo” button called Multi-threading (/MT).

1. The “Standard” Lazy Migration Command

If you just want to move a folder and make sure all the permissions (ACLs) stay intact, this is your go-to string:

ROBOCOPY C:\sourcefolder C:\destinationfolder /E /COPY:DATS /LOG+:C:\temp\Robocopy_logs.txt

  • /E: Copies all subfolders, even the empty ones.
  • /COPY:DATS: This is the magic. It copies Data, Attributes, Timestamps, and Security (NTFS ACLs).
  • /LOG+: Appends the results to a text file. Always log your copies. If something is missing later, the log is your evidence.

2. Going “Turbo” with Multi-Threading (/MT)

By default, Windows copies files one by one (Serial). With the /MT switch, you can open up to 128 “lanes” of traffic.

  • Default: /MT:8 (8 files at once)
  • Aggressive: /MT:32 (Sweet spot for most servers)
  • Extreme: /MT:128 (Use this for thousands of tiny files)

Pro Tip: /MT is not compatible with /IPG (which slows down copies to save bandwidth) or /EFSRAW. If you want speed, stick to /MT.


3. Real-World Examples: Migrating Mapped Drives

When migrating large volumes (like a mapped Y: or Z: drive), you want to use the /MIR (Mirror) switch. This makes the destination an exact clone of the source.

Example: Migrating a Production Volume

ROBOCOPY Y:\lfvolumes\DEFAULT E:\MIGRATE_PRD\E_Drive /MIR /MT:24 /LOG+:D:\Logs\Edrive.txt

Example: Copying a Single Giant SQL Backup (.BAK)

ROBOCOPY T:\ E:\Migrations\ db_backup.BAK /ZB /J /LOG+:D:\Logs\backup.txt

  • /ZB: Restartable mode (if the network drops, it picks up where it left off).
  • /J: Unbuffered I/O (Recommended for huge files like database backups).

4. The “Cheat Sheet” of Switches

SwitchWhat it does
/MIRMirroring. Deletes files in destination that no longer exist in source.
/ZRestartable Mode. Survives network glitches.
/R:nNumber of retries (Default is 1 millionโ€”set this to 3 or 5 instead!).
/W:nWait time between retries (Default is 30 seconds).
/FFTUse this if copying to a Linux NAS to avoid timestamp issues.

๐Ÿ›ก๏ธ Lazy Admin Warning:

Be careful with /MIR. If you accidentally point it at an empty source folder, it will “Mirror” that emptiness by deleting everything in your destination. Always test with the /L (List Only) switch first to see what would happen without actually doing it.

Finding RDM LUN UUIDs in a vSphere Cluster | LazyAdminBlog.com

Posted on Updated on

If youโ€™re managing a large virtual environment, keeping track of Raw Device Mappings (RDMs) can be a nightmare. Unlike standard virtual disks (VMDKs) that live neatly inside a datastore, RDMs are directly mapped to a LUN on your SAN.

When your storage team asks, “Which VM is using LUN ID 55?”, you don’t want to check every VM manually. This PowerCLI script will scan your entire cluster and export a list of all RDMs along with their Canonical Name (NAA ID) and Device Name.


The PowerCLI One-Liner

This command connects to your cluster, filters for disks that are either RawPhysical (Pass-through) or RawVirtual, and spits out the details to a text file for easy searching.

Run this in your PowerCLI window:

PowerShell

Get-Cluster 'YourClusterName' | Get-VM | Get-HardDisk -DiskType "RawPhysical","RawVirtual" | Select-Object @{N="VM";E={$_.Parent.Name}},Name,DiskType,ScsiCanonicalName,DeviceName | Format-List | Out-File โ€“FilePath C:\temp\RDM-list.txt

Breaking Down the Output

Once you open C:\temp\RDM-list.txt, here is what you are looking at:

  • Parent: The name of the Virtual Machine.
  • Name: The label of the hard disk (e.g., “Hard disk 2”).
  • DiskType: Confirms if it’s Physical (direct SCSI commands) or Virtual mode.
  • ScsiCanonicalName: The NAA ID (e.g., naa.600601...). This is the “Universal ID” your storage array uses.
  • DeviceName: The internal vSphere path to the device.

Why do you need this?

  1. Storage Migrations: If you are decommissioning a storage array, you must identify every RDM to ensure you don’t leave a “Ghost LUN” behind.
  2. Troubleshooting Performance: If a specific LUN is showing high latency on the SAN side, this script tells you exactly which VM is the “noisy neighbor.”
  3. Audit & Compliance: Great for keeping a monthly record of physical hardware mappings.

Lazy Admin Note: This script specifically uses VMware PowerCLI cmdlets (Get-HardDisk). If you are looking for similar info on a Hyper-V host, you would typically use Get-VMHardDiskDrive and look for the DiskNumber property to correlate with physical disks in Disk Management.

Hyper-V Performance Hack: The Essential Antivirus Exclusions List | LazyAdminBlog.com

Posted on Updated on

Running antivirus on your Hyper-V host is a security must, but if you don’t configure it correctly, you’re asking for trouble. We’re talking “disappearing” VMs, corrupted virtual disks, and performance so sluggish you’ll think you’re back on physical hardware from 2005.

The culprit is usually the Real-Time Scanning engine trying to “inspect” a 100GB .vhdx file every time the guest OS writes a single bit. Here is the definitive “Lazy Admin” guide to Hyper-V AV exclusions.


1. File Extension Exclusions

Tell your AV to keep its hands off these specific virtual machine file types:

  • Virtual Disks: .vhd, .vhdx
  • Snapshots/Checkpoints: .avhd, .avhdx
  • Saved State: .vsv, .bin, .vmgs
  • Configuration: .xml, .vmcx, .vmrs
  • ISO Images: .iso
  • Tracking: .rct (Resilient Change Tracking)

2. Directory Exclusions

If you are using the default paths, exclude these. If you have a dedicated D:\VMs drive (which you should!), exclude that entire custom path as well.

  • Default Configs: C:\ProgramData\Microsoft\Windows\Hyper-V
  • Default VHDs: C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks
  • Default Snapshots: C:\ProgramData\Microsoft\Windows\Hyper-V\Snapshots
  • Cluster Shared Volumes (CSV): C:\ClusterStorage
  • Hyper-V Replica: Any custom replication data folders.
  • SMB 3.0 Shares: If your VMs live on a remote file server, apply these same exclusions to that file server!

Lazy Admin Pro-Tip: If you’re using a Cluster, don’t just exclude the C:\ClusterStorage folder by path. Use the Volume ID (get it via mountvol) to ensure the exclusion sticks even if drive letters or paths shift.

3. Process Exclusions

Sometimes excluding the file isn’t enough; you need to exclude the “person” opening the file. Exclude these core Hyper-V executables:

  • Vmms.exe: The Virtual Machine Management Service.
  • Vmwp.exe: The Virtual Machine Worker Process (one runs for every active VM).
  • Vmcompute.exe: (For Windows Server 2019+) The Host Compute Service.

Why this matters (The “Error 0x800704C8”)

If you don’t set these, you’ll eventually see the dreaded Error 0x800704C8 (The process cannot access the file because it is being used by another process). This happens when your AV locks the VM’s configuration file exactly when Hyper-V tries to start it.

What about Windows Defender?

Good news for the truly lazy: if you are using built-in Microsoft Defender on Windows Server, it automatically detects the Hyper-V role and applies most of these exclusions for you. However, it does not always catch your custom storage paths (like E:\MyVMs), so always double-check your work!

Level Up: Becoming a Zerto Certified Professional (ZCP)ย | LazyAdminBlog.com

Posted on Updated on

In the world of Disaster Recovery, there are two types of admins: those who panic during an outage, and those who have “Master of Disaster” status.

If you’re looking to join the elite ranks of the latter, itโ€™s time to talk about Zerto Certified Professional (ZCP) training. While the original ZVR 4.5 training was a game-changer for its time, Zertoโ€™s training ecosystem has evolved significantly since then to keep pace with modern cloud and ransomware threats.


What is ZCP Training?

Zerto Certified Professional (ZCP) is the official technical certification program designed for customers and partners. It moves you beyond the basics of “click and replicate” into the deep engineering of Continuous Data Protection (CDP).

The current curriculum has shifted from just “Basic” to a more modular, role-based approach available through the myZerto University platform.

Key Learning Pillars:

  • Architecture & Installation: Setting up the Zerto Virtual Manager (ZVM) and Virtual Replication Appliances (VRAs).
  • VPG Management: Creating Virtual Protection Groups (VPGs) to keep multi-VM applications consistent.
  • The “Time Machine” (Journal): Master file-level restores and point-in-time recovery to defeat ransomware.
  • The Big Red Button: Coordinating Test Failovers, Live Failovers, and Move operations without breaking a sweat.

Is it still “Basic”?

Zerto has streamlined its certifications into several paths to match your specific environment:

CertificationLevelFocus Area
ZCP EnterpriseFoundationCore vSphere/Hyper-V to On-Prem replication.
ZCP Azure/AWSIntermediateHybrid Cloud DR and migration to public clouds.
ZCP AdvancedExpertComplex troubleshooting, multi-site, and API automation.
ZCP Managed ServicesPartnerSpecifically for DRaaS (Disaster Recovery as a Service) providers.

Why Bother Getting Certified?

  1. Confidence: Knowing exactly how the journal works means you can recover data from seconds before a crash.
  2. Professional Status: It officially recognizes you as a “Master of Disaster” within the community.
  3. Efficiency: You’ll learn the “Lazy Admin” way to automate IP re-addressing and boot ordering, so you don’t have to do it manually during a crisis.

How to Get Started

  1. Access: Head over to the myZerto Portal. (Note: You still need to be a customer or partner to access full technical training).
  2. Time Investment: Most foundational courses take between 90 minutes and 3 hours of self-paced e-learning.
  3. The Exam: Youโ€™ll typically need a 75% or higher to pass. The exams are online, unproctored, and refreshingly focused on real-world scenarios rather than trivia.

Lazy Admin Tip: Don’t just watch the videos. If you have a lab environment, try to break a VPG and see how the ZVM alerts you. Real learning happens when the lights go red!

Fixing Corrupt Image Profiles on ESXi | LazyAdminBlog.com

Posted on Updated on

Weโ€™ve all been thereโ€”a patch remediation task in vSphere Update Manager (VUM) or vSphere Lifecycle Manager (vLCM) gets interrupted (shoutout to that one colleague!), and suddenly your ESXi host is in a “zombie” state.

If you see the dreaded “Unknown – no profile defined” error, your host has lost its identity. It no longer knows which VIBs (VMware Installation Bundles) should be installed. This is usually caused by a corrupt imgdb.tgz file.

Weโ€™ve all been thereโ€”a patch remediation task in vSphere Update Manager (VUM) or vSphere Lifecycle Manager (vLCM) gets interrupted (shoutout to that one colleague!), and suddenly your ESXi host is in a “zombie” state.

If you see the dreaded “Unknown – no profile defined” error, your host has lost its identity. It no longer knows which VIBs (VMware Installation Bundles) should be installed. This is usually caused by a corrupt imgdb.tgz file.

image profile issue

The Symptom: Missing Image Profile

When an image profile is empty or corrupt, you cannot install patches, remove drivers, or perform upgrades. ESXi relies on the image database to maintain consistency.

How to Diagnose a Corrupt imgdb.tgz

Before you resort to a full host rebuild, verify the file size of the database. A healthy imgdb.tgz is typically around 26 KB. If yours is only a few bytes, itโ€™s corrupted.

  1. SSH into the host.

  2. Locate the files:

    cd /vmfs/volumes
    find * | grep imgdb.tgz
  3. Note: You will usually see two results (one for each bootbank).

  4. Check the size:

    ls -l <path_to_result>/imgdb.tgz

    If the size is tiny (e.g., 0-100 bytes), the database is toast.


The Fix: Borrowing a “Known Good” Profile

Instead of a time-consuming reinstall, you can manually restore the database from a healthy host running the exact same version and patch level.

Step 1: Export from a Healthy Host

On a working ESXi host, copy the healthy database to a shared datastore:

cp /bootbank/imgdb.tgz /vmfs/volumes//

Step 2: Restore on the Corrupt Host

On the host with the issue, move the good file to /tmp and extract it to access the internal VIB and Profile metadata:

cp /vmfs/volumes//imgdb.tgz /tmp
cd /tmp
tar -xzf imgdb.tgz

Step 3: Rebuild the Database Directories

Now, manually place the healthy metadata into the system directories:

  1. Copy Profiles: cp /tmp/var/db/esximg/profiles/* /var/db/esximg/profiles/

  2. Copy VIBs: cp /tmp/var/db/esximg/vibs/* /var/db/esximg/vibs/

  3. Replace Bootbank File:

    rm /bootbank/imgdb.tgz
    cp /tmp/imgdb.tgz /bootbank/

Step 4: Finalize and Persist

To ensure these changes survive a reboot, run the backup script:

/sbin/auto-backup.sh

Summary Table: Resolution Options

OptionEffortRiskWhen to use
Rebuild HostHighLowIf you don’t have a matching “known good” host.
Manual File CopyLowMediumWhen you need a fast fix and have a twin host available.

Forgot Your ESXi Root Password? Reset It Without Reinstalling (vCenter Hack)

Posted on Updated on

Weโ€™ve all been there. You go to log into the DCUI or SSH into a host only to find the root password doesn’t work, and nobody documented the change.

According to VMwareโ€™s official stance, the only “supported” way to recover is a complete wipe and reinstall. But if your host is still managed by vCenter and you have Enterprise Plus licensing, there is a “lazy” (and highly effective) way out using Host Profiles.

How it works

When a host is added to vCenter, a special user called vpxa is created with full root privileges. We can use this existing “backdoor” to push a new configuration to the host, effectively overwriting the lost root password.


Step-by-Step Recovery

1. Extract the Profile

Right-click the “locked” host in the vSphere Web Client. Navigate to All vCenter Actions > Host Profiles > Extract Host Profile. Follow the wizard to create a template of that specific host’s configuration.

2. Edit the Security Settings

Go to Home > Host Profiles (under Management). Right-click your new profile and select Edit.

  • Expand Security and Services.
  • Expand Security Settings.
  • Click on Security Configuration.
  • In the dropdown, select: โ€œConfigure a fixed administrator passwordโ€.
  • Enter and confirm your new root password.

3. Attach and Remediate

  1. Go back to Hosts and Clusters, right-click the host, and select Host Profiles > Attach Host Profile. Select the one you just edited.
  2. Maintenance Mode: You must put the host into Maintenance Mode.
  3. Remediate: Right-click the host again, select Host Profiles > Remediate. If you skip Maintenance Mode, vSphere will block the operation.

4. Finish

Once the remediation task completes, the host will reboot. Your new root password is now active!


Important Limitations

  • Licensing: This requires Enterprise Plus. Standard or Essentials kits do not include Host Profiles.
  • Connectivity: The host must be currently “Connected” in vCenter. If the management agent has crashed or the host is “Not Responding,” this method will not work.

The “Lazy Admin” Verdict

Reinstalling an ESXi host means reconfiguring networking, storage, and scratch partitions. Using a Host Profile takes about 10 minutes and keeps your uptime (and sanity) intact.

The Clean Exit: How to Safely Remove Storage Devices from ESXi

Posted on Updated on

In the world of storage, “unpresenting” a LUN is more than just a right-click. If you don’t follow the proper decommissioning workflow, ESXi will keep trying to talk to a ghost device, leading to host instability and long boot times.

Follow this definitive checklist and procedure to ensure your environment stays clean and APD-free.

The “Safe-to-Remove” Checklist

Before you even touch the unmount button, verify these 7 critical points:

  1. Evacuate Data: Move or unregister all VMs, snapshots, templates, and ISO images from the datastore.
  2. HA Heartbeats: Ensure the datastore is NOT being used for vSphere HA heartbeats.
  3. No Clusters: Remove the datastore from any Datastore Clusters or Storage DRS management.
  4. Coredump: Confirm the LUN isn’t configured as a diagnostic coredump partition.
  5. SIOC: Disable Storage I/O Control (SIOC) for the datastore.
  6. RDMs: If the LUN is an Raw Device Mapping, remove the RDM from the VM settings (select “Delete from disk” to kill the mapping file).
  7. Scratch Location: Ensure the host isn’t using this LUN for its persistent scratch partition.

Pro Tip: Check Scratch Location via PowerCLI

Use this script to verify your scratch config across a cluster:

PowerShell
$cluster = "YourClusterName"
foreach ($esx in Get-Cluster $cluster | Get-VMHost) {
Get-VMHostAdvancedConfiguration -VMHost $esx -Name "ScratchConfig.ConfiguredScratchLocation"
}

Step 1: Identify your NAA ID

You need the unique Network Address Authority (NAA) ID to ensure you are pulling the right plug.

  • Via GUI: Check the Properties window of the datastore.
  • Via CLI: Run esxcli storage vmfs extent list

Step 2: The Unmount & Detach Workflow

1. Unmount the File System

In the Configuration tab > Storage, right-click the datastore and select Unmount. If you are doing this for multiple hosts, use the Datastores view (Ctrl+Shift+D) to unmount from the entire cluster at once.

2. Detach the Device (The Most Important Step)

Unmounting removes the “logical” access, but Detaching tells the kernel to stop looking for the “physical” device.

  • Switch to the Devices view.
  • Right-click the NAA ID and select Detach.
  • The state should now show as Unmounted.

Note: Detaching is a per-host operation. You must perform this on every host that has visibility to the LUN to avoid APD states.


Step 3: Cleanup the SAN & Host

Once the state is “Unmounted” across all hosts, you can safely unmap/unpresent the LUN from your SAN array.

Permanent Decommissioning

To prevent “ghost” entries from appearing in your detached list, run these commands on the host:

  1. List detached devices: esxcli storage core device detached list
  2. Remove the configuration permanently: esxcli storage core device detached remove -d <NAA_ID>

The Master List: VMware vCenter Release & Build Number History (Updated 2026)

Posted on Updated on

Version tracking is the backbone of lifecycle management. Whether you are patching against the latest security vulnerability or verifying compatibility for a backup agent, you need the exact build number.

Below is the comprehensive history of vCenter Server, from the cutting-edge vSphere 9.0 down to the legacy VirtualCenter 2.5.

vCenter Server 9.0 Build Numbers (Latest)

vSphere 9.0 represents the latest shift toward AI-integrated infrastructure and cloud-native operations.

NameVersionRelease DateBuild Number
vCenter Server 9.0.2.09.0.201/20/202625148086
vCenter Server 9.0.1.09.0.109/29/202524957454
vCenter Server 9.0 GA9.0.006/17/202524755230

vCenter Server 8.0 Build Numbers

The 8.0 Update 3 branch is the current stable “workhorse” for most enterprise environments.

NameVersionRelease DateBuild Number
vCenter Server 8.0 Update 3i8.0.3.0080002/24/202625197330
vCenter Server 8.0 Update 3h8.0.3.0070012/15/202525092719
vCenter Server 8.0 Update 3g8.0.3.0060007/29/202524853646
vCenter Server 8.0 Update 3e8.0.3.0050004/11/202524674346
vCenter Server 8.0 Update 38.0.3.0000006/25/202424022515
vCenter Server 8.0 Update 28.0.2.0000009/21/202322385739
vCenter Server 8.0 Update 18.0.1.0000004/18/202321560480
vCenter Server 8.0 GA8.0.0.1000010/11/202220519528

vCenter Server 7.0 Build Numbers

Note: vCenter for Windows was officially removed starting with version 7.0.

NameVersionRelease DateBuild Number
vCenter Server 7.0 Update 3w7.0.3.0250009/29/202524927011
vCenter Server 7.0 Update 3l7.0.3.0140003/30/202321477706
vCenter Server 7.0 Update 27.0.2.0000003/09/202117694817
vCenter Server 7.0 GA7.0.0.1010004/02/202015952498

Legacy vCenter Server Build Numbers (vSphere 4.0 โ€“ 6.7)

NameVersionRelease DateBuild Number
vCenter Server 6.7 Update 3w6.7.0.5800010/28/202424337536
vCenter Server 6.5 Update 3w6.5.0.4300007/04/202424045034
vCenter Server 6.0 Update 16.0 U109/10/20153018524
vCenter Server 5.5 Update 35.5 U309/16/20153000241
vCenter Server 5.1 Update 35.1 U312/04/20142306353
vCenter Server 5.0 GA5.0 GA08/24/2011456005
vCenter Server 4.1 GA4.1 GA07/13/2010259021
vCenter Server 4.0 GA4.0 GA05/21/2009162856
VirtualCenter 2.5.0 GA2.5.012/10/200764192

Quick Tips for the Lazy Admin

  1. Check via VAMI: For 6.7 and newer, go to https://<vcenter-ip>:5480. The version and build are right on the login screen.
  2. Compatibility: Before upgrading vCenter, check the VMware Interoperability Matrix. Just because vCenter 9.0 is out doesn’t mean your older ESXi 6.7 hosts can talk to it!
  3. VCSA Migration: If you are still on version 6.5 or 6.7, your next step is a migration to the Appliance (VCSA). There is no “in-place” upgrade for Windows-based vCenter to 7.0+.

#VMware #vSphere9 #vCenter #SysAdmin #Virtualization #Datacenter #LazyAdmin #BuildNumbers #ITOps #PatchManagement

Locked Out of Cisco UCS? How to Recover the Master Admin Password

Posted on Updated on

Itโ€™s the nightmare scenario: you need to make a critical service profile change, but the only admin password is lost or forgotten. Because Cisco UCS Manager doesn’t store passwords in a reversible format, you can’t “view” the old one. Instead, you must perform a password reset by power-cycling the Fabric Interconnects (FIs) and interrupting the boot sequence.

โš ๏ธ Warning: This procedure requires a physical power cycle of the Fabric Interconnects. In a production environment, this will cause a temporary disruption in management connectivity and potentially data traffic if not handled correctly in a cluster.


Phase 1: The Pre-Flight Check

Before you pull the power cables, you need two pieces of information. If you still have read-only access or a lower-privilege account, gather these now:

  1. Identify the Roles: In a cluster, you must know which FI is Primary and which is Subordinate.
    • Path: Equipment > Fabric Interconnects > [FI Name] > General > High Availability Details.
  2. Verify Firmware Versions: You must know the exact Kernel and System firmware versions currently running.
    • Path: Equipment > Firmware Management > Installed Firmware.

Phase 2: Password Recovery (The Process)

Scenario A: Standalone Configuration

If you only have one Fabric Interconnect, the process is straightforward but requires downtime.

  1. Connect: Attach a console cable physically to the FI console port.
  2. Power Cycle: Turn the FI off and then back on.
  3. Interrupt Boot: As it boots, repeatedly press Ctrl+L or Ctrl+Shift+R until you see the loader > prompt.
  4. Boot Kernel: Load the kickstart/kernel image: loader > boot /installables/switch/ucs-6100-k9-kickstart.x.x.x.gbin
  5. Enter Config: Fabric(boot)# config terminal
  6. Reset Password: Fabric(boot)(config)# admin-password YourNewPassword123
  7. Load System: Exit config mode and boot the system image: Fabric(boot)# load /installables/switch/ucs-6100-k9-system.x.x.x.bin

Scenario B: Cluster Configuration (High Availability)

In a cluster, the order of operations is vital to ensure the database remains synchronized.

  1. Subordinate First: Power cycle the Subordinate FI and interrupt its boot to the loader > prompt. Leave it there.
  2. Primary Second: Power cycle the Primary FI and interrupt its boot to the loader > prompt.
  3. Reset on Primary: Follow the “Standalone” steps (4 through 7) on the Primary FI console.
  4. Bring up Subordinate: Once the Primary is back up and you can log into UCS Manager, go to the Subordinate console and boot its kernel and system images normally from the loader prompt.

Important Notes

  • Clear Text: When you type the admin-password command in the boot loader, the password displays in clear text on the screen. Ensure no one is shoulder-surfing!
  • Strong Passwords: UCS Manager requires at least one capital letter and one number.
  • Console Access: This cannot be done via SSH. You must have physical or terminal server access to the console port.

#CiscoUCS #DataCenter #CiscoProphet #SysAdmin #Networking #ITTech #Cisco #UCSManager #LazyAdmin #Infrastructure

No Reboot Required: Configuring Dell iDRAC via RACADM

Posted on Updated on

Configuring the Integrated Dell Remote Access Controller (iDRAC) is usually a “Day 1” task performed in the BIOS. But what if youโ€™ve already deployed the server and realized the NIC isn’t configured, or the IP needs to change?

By using the Dell RACADM (Remote Access Controller Admin) utility, you can modify network settings, reset credentials, and pull system health logs directly from the command line without a single second of downtime.

Getting the Tools

To start, download the Dell EMC OpenManage DRAC Tools. This package includes the RACADM executable. You can install this on the local server or on your management workstation to manage servers over the network.


1. Remote RACADM (From your Workstation)

If you have the current credentials but need to change settings remotely, use the -r (remote), -u (user), and -p (password) flags.

Example: Get System Information

Bash

racadm -r 10.1.1.1 -u root -p calvin getsysinfo

Note: If you get an SSL certificate error, the command will still run. To force the command to stop on certificate errors for security, add the -S flag.


2. Local RACADM (From the Server OS)

If you are logged into the Windows or Linux OS on the Dell server itself, you don’t need credentials. The tool communicates directly with the hardware via the IPMI driver.

Example: Quick Network Setup

Bash

# Check current config
racadm getniccfg
# Set a new Static IP, Subnet, and Gateway
racadm setniccfg -s 192.168.1.50 255.255.255.0 192.168.1.1

3. Deep Configuration (The Config Group Method)

For more granular control (like setting DNS servers or the DRAC name), you can target specific configuration groups.

The “Lazy Admin” DNS Setup Script:

Bash

racadm config -g cfgLanNetworking -o cfgNicIpAddress 172.17.2.124
racadm config -g cfgLanNetworking -o cfgNicNetmask 255.255.252.0
racadm config -g cfgLanNetworking -o cfgDNSServer1 172.17.0.6
racadm config -g cfgLanNetworking -o cfgDNSRacName MyServer-iDRAC
racadm config -g cfgLanNetworking -o cfgDNSDomainName corp.company.com

4. SSH / Serial RACADM

If you are already connected to the iDRAC via SSH, you don’t need to repeat the racadm command prefix. Simply type racadm and hit enter to enter the RACADM shell:

Bash

admin@idrac-web-01: racadm
racadm>> getsysinfo
racadm>> serveraction powercycle

Why this is a “Lazy Admin” Win

Instead of walking to the cold aisle with a crash cart or waiting for a 20-minute reboot cycle, you can script the iDRAC configuration of an entire rack in seconds.

#DellEMC #PowerEdge #iDRAC #SysAdmin #DataCenter #RACADM #Infrastructure #ITOps #LazyAdmin #ServerManagement

HPE Support 101: A Step-by-Step Guide to Raising ProLiant & Blade Server Cases

Posted on Updated on

Is your ProLiant DL360 Gen11 throwing a pre-failure alert? Or perhaps a BL460c blade has gone “No Power” in the chassis? Since the segregation of HP into HP Inc. and Hewlett Packard Enterprise (HPE), the support portal has evolved.

If you are a “Lazy Admin,” you want to get your ticket in quickly so you can get back to what matters. Here is the streamlined approach to navigating HPE Support.

Step 1: Identify Your Product Family

Before heading to the portal, confirm which category your hardware falls into. HPE generally groups them as:

  • BL Series: ProLiant Server Blades (Enclosure-based)
  • DL Series: Rack-mount Servers (Multi-node and Standard)
  • ML Series: Tower Servers
  • MicroServer: For small office/home office environments
  • Apollo/Scalable Systems: High-density computing

Step 2: Use the Global Search

If you aren’t sure which specific “Packaged Cluster” or “Scalable System” you have, use the HPE Support Center search bar. Enter your specific model (e.g., ProLiant DL380 Gen10).

Why this page is useful: Before you even raise a case, the product page provides:

  • Top Issues & Solutions: Often, the fix for a known firmware bug is already listed here.
  • Drivers & Software: Essential for getting the latest SPP (Service Pack for ProLiant).
  • Warranty Check: Crucial! HPE will not open a case for hardware replacement if the serial number isn’t linked to an active contract or warranty.

Step 3: The HP Passport Login

To submit or manage cases, you must have an HPE Passport account. This is a single sign-on (SSO) service.

You can access the login page directly here: https://support.hpe.com/hpesc/public/home/

  • Tip: Link your companyโ€™s Support Agreement IDs (SAID) or Service Agreement IDs (SAR) to your Passport account before the server fails. It saves massive amounts of time during an actual emergency.

Step 4: Submitting the Case

Navigate to the Submit or manage support cases section. You will need:

  1. Serial Number (S/N): Found on the pull-out “luggage tag” on the front of the server or via iDRAC/iLO.
  2. Product Number (P/N): The specific hardware SKU.
  3. Logs: HPE will almost always ask for an Active Health System (AHS) log. Download this from the iLO before you start the ticket.

#HPE #ProLiant #ServerSupport #SysAdmin #DataCenter #ITOps #HPEPassport #Troubleshooting #LazyAdmin #EnterpriseIT

vSphere Ports & Connections: The Infrastructure Roadmap

Posted on Updated on

In a locked-down enterprise environment, the “Any-to-Any” firewall rule is a myth. To manage ESXi effectively, you need to poke specific holes in your hardware and software firewalls.

The Core Management Ports

These are the “must-haves” for basic connectivity between vCenter, the vSphere Client, and the Host.

PortProtocolSourceDestinationPurpose
443TCPManagement WorkstationvCenter / ESXivSphere Client / SDK: The primary port for the Web Client and API access.
902TCP/UDPvCenter ServerESXi HostvCenter Agent (vpxa): vCenter uses this to send data to the host and receive heartbeats.
902TCPManagement WorkstationESXi HostVM Console: Required to open the “Remote Console” (MKS) to a virtual machine.
80TCPvCenter / WorkstationESXi HostHTTP: Used for redirecting to 443 and for some legacy file downloads.

Advanced Feature Ports

If you are using specific vSphere features like vMotion, HA, or specialized storage, you need these additional ports open:

1. vMotion (Live Migration)

  • 8000 (TCP): Required for vMotion traffic.
  • 2049 (TCP/UDP): If using NFS storage for the virtual disks.

2. vSphere High Availability (HA)

  • 8182 (TCP/UDP): Used by the Fault Domain Manager (FDM) agent for inter-host communication and election of the master host.

3. Provisioning & Deployment

  • 69 (UDP): TFTP, used for PXE booting ESXi for Auto Deploy.
  • 4012 (TCP): Used by the Auto Deploy service.

4. Troubleshooting & Monitoring

  • 22 (TCP): SSH access to the ESXi Shell.
  • 161 / 162 (UDP): SNMP polling and traps for hardware monitoring.

Troubleshooting “Host Disconnected”

If your host shows as “Not Responding” in vCenter, check these three things in order:

  1. Ping: Can the vCenter server ping the ESXi management IP?
  2. Port 902: From the vCenter server, try to telnet to the host on port 902 (telnet <host-ip> 902). If it fails, the heartbeat can’t get through.
  3. DNS: VMware is extremely sensitive to DNS. Ensure forward and reverse lookups work for both the vCenter and the Host.

Lazy Admin Tip ๐Ÿ’ก

Don’t memorize every port! Use the VMware Ports and Protocols Tool (the official online matrix). It allows you to select your source and destination products and generates a custom firewall rule list for you.

A high resolution pdf can be downloaded hereย Connections and Ports in ESX and ESXi

#VMware #vSphere #Networking #SysAdmin #Firewall #DataCenter #ESXi #ITOps #LazyAdmin #Connectivity

The Master List: VMware ESXi Release and Build Number History

Posted on Updated on

Is your host up to date? Checking the “About” section in your vSphere Client is step one, but cross-referencing that number against this list is how you confirm if you’re on a General Availability (GA) release, an Update, or an Express Patch.

vSphere ESXi 9.0 (Latest)

The new generation of the hypervisor, optimized for AI workloads and DPUs.

NameVersionRelease DateBuild Number
VMware ESXi 9.0.29.0.22026-01-2025148080
VMware ESXi 9.0.19.0.12025-09-2924957450
VMware ESXi 9.0 GA9.0 GA2025-06-1724755225

vSphere ESXi 8.0

The enterprise workhorse for 2024-2026.

NameVersionRelease DateBuild Number
VMware ESXi 8.0 Update 38.0 U32024-06-2524022510
VMware ESXi 8.0 Update 28.0 U22023-09-2122380479
VMware ESXi 8.0 Update 18.0 U12023-04-1821495797
VMware ESXi 8.0 GA8.0 GA2022-10-1120513097

vSphere ESXi 7.0

Note: This version introduced the new Lifecycle Manager (vLCM).

NameVersionRelease DateBuild Number
VMware ESXi 7.0 Update 3w7.0 U3w2025-09-2924927030
VMware ESXi 7.0 Update 37.0 U32021-10-0518644231
VMware ESXi 7.0 GA7.0 GA2020-04-0215843807

vSphere ESXi 6.x Legacy (Archive)

NameVersionRelease DateBuild Number
VMware ESXi 6.7 Update 36.7 U32019-08-2014320388
VMware ESXi 6.5 Update 36.5 U32019-07-0213932383
VMware ESXi 6.0 Update 1a6.0 U1a2015-10-063073146
VMware ESXi 6.0 GA6.0 GA2015-03-122494585

How to Verify Your Build Number

If you aren’t at your desk and only have SSH access to the host, you can find your build number instantly with this command:

vmware -v

Example Output:

VMware ESXi 8.0.0 build-20513097

Lazy Admin Tip ๐Ÿ’ก

Always remember the vCenter Interoperability Rule: Your vCenter Server must always be at a build version equal to or higher than your ESXi hosts. If you patch your hosts to vSphere 9.0 while vCenter is still on 8.0, your hosts will show as “Not Responding” or “Disconnected.”

#VMware #vSphere9 #ESXi #SysAdmin #Virtualization #PatchManagement #DataCenter #LazyAdmin #BuildNumbers #ITOperations

Emergency Log Collection: Generating and Uploading ESXi Support Bundles

Posted on Updated on

If you can’t generate a support bundle through vCenter, your best bet is the ESXi Shell. By running vm-support directly on the host, you bypass the management overhead and get your diagnostics faster.

Step 1: Generate Logs via SSH (CLI)

Before running the command, identify a datastore with at least 5-10GB of free space to store the compressed bundle.

  1. SSH into your ESXi host using Putty.
  2. Navigate to your chosen datastore: cd /vmfs/volumes/YOUR_DATASTORE_NAME/
  3. Run the support command and redirect the output to a specific file name:Bashvm-support -s > vm-support-HostName-$(date +%Y%m%d).tgz
    • -s stands for “stream,” directing the output to the file you specified.
    • Tip: Using $(date +%Y%m%d) automatically adds the current date to the filename.
  4. Once finished, use the vSphere Datastore Browser to download the .tgz file to your local workstation.

Step 2: Uploading to VMware via FileZilla

VMware provides a public FTP/SFTP landing zone for Support Requests (SR). While many admins use the browser, a dedicated client like FileZilla is much more reliable for large multi-gigabyte bundles.

Configure FileZilla for VMware

  1. Set Transfer Mode: Go to Transfer > Transfer type > Binary. This prevents file corruption during the upload.
  2. Open Site Manager: (File > Site Manager) and create a new site:
    • Host: ftpsite.vmware.com
    • Protocol: FTP (or SFTP if requested by support)
    • Logon Type: Normal
    • User: inbound
    • Password: inbound

Navigating the Remote Site

  1. Connect to the server.
  2. Create your SR Folder: In the “Remote Site” pane, right-click and select Create Directory. Name it exactly after your 10-digit Support Request number (e.g., 2612345678).
  3. Upload: Locate your .tgz bundle in the left pane (Local Site), right-click it, and select Upload.

Important Note: For security, the VMware FTP is “blind.” You will not see your files or folders once they are created/uploaded. Don’t panic if the directory looks empty after the transfer completes; as long as the transfer queue shows 100%, VMware has it.

#VMware #ESXi #Troubleshooting #SysAdmin #DataCenter #Virtualization #ITOps #FileZilla #LazyAdmin #TechTips

Nuclear Option: How to Force Power Off a Hung VM via SSH

Posted on Updated on

Weโ€™ve all been there: a Windows Update goes sideways or a database lock freezes a guest OS, and suddenly the “Shut Down Guest” command is greyed out or simply times out. When the GUI fails you, the ESXi Command Line (esxcli) is your best friend.

Step 1: Identify the “World ID”

In ESXi terminology, every running process is assigned a World ID. To kill a VM, you first need to find this unique identifier.

  1. SSH into your ESXi host using Putty.
  2. Run the following command to see all active VM processes:Bashesxcli vm process list
  3. Locate your hung VM in the list. Look for the World ID (a long string of numbers). You will also see the Display Name and the path to the .vmx file to confirm you have the right one.

Step 2: Execute the Kill Command

ESXi offers three levels of “force” to stop a process. It is best practice to try them in order:

  1. Soft: The most graceful. It attempts to give the guest OS a chance to shut down cleanly.
  2. Hard: Equivalent to pulling the power cable. Immediate cessation of the VMX process.
  3. Force: The “last resort.” Use this only if ‘Hard’ fails to clear the process from the kernel.

The Syntax:

Bash

esxcli vm process kill --type=[soft,hard,force] --world-id=WorldNumber

Example (Hard Kill): esxcli vm process kill -t hard -w 5241852


Step 3: Verify the Result

After running the kill command, it may take a few seconds for the host to clean up the memory registration. Run the list command again to ensure itโ€™s gone:

Bash

esxcli vm process list | grep "Your_VM_Name"

If the command returns nothing, the VM is officially offline, and you can attempt to power it back on via the vSphere Client.

Lazy Admin Tip ๐Ÿ’ก

If esxcli still won’t kill the VM, the process might be stuck in an “I/O Wait” state (usually due to a failed storage path). In that rare case, you might actually need to restart the Management Agents (services.sh restart) or, in extreme cases, reboot the entire host.

#VMware #vSphere #ESXi #SysAdmin #Troubleshooting #Virtualization #ITOps #LazyAdmin #ServerManagement #DataCenter

How to fix a RDP issue without reboot?

Posted on Updated on

The following steps can be used to resolve RDP issues without a restart:

ย Note: The below condition will be applicable only if the server is available on NetworkJ.

ย ย Troubleshooting Steps:

1. Check if the Windows Firewall Setting is Enabled on the server. If yes, have them Disabled.

ย Note: This is primarily applicable for Virtual Servers (VM machines) and if it is accessible in VM console.

 

ย 2.ย The following registry location, which is responsible for Terminal Server to access the via RDP:

ย HKEY_LOCAL_MACHINE \SYSTEM\CurrentControlSet\Control\Terminal Server

ย Under the Terminal Server key, the REG_DWORD value named fDenyTSConnection should be 0 because the value data 1 denies connecting to Terminal Services (to access the server via RDP).

ย Note: Even if the value is 0, change it from 0 to 1 and refresh the registry. Again the change the value back from 1 to 0 and refresh the registry.

ย HKEY_LOCAL_MACHINE \SYSTEM\CurrentControlSet\Control\Terminal Server

ย Under the Terminal Server key, the REG_DWORD value named fAllowToGetHelp should be 0 because the value data 1 denies the Remote Assistance on a server (to access the server via RDP).

Note: Even if the value is 0, change it from 0 to 1 and refresh the registry. Again the change the value back from 1 to 0 and refresh the registry.

3. The following registry location is used to enable Remote User Session on a server (Citrix)

ย HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\ICA-Tcp

ย Under the ICA-Tcp key, the REG_DWORD value named fEnableWinStation should be 1 because the value data 0 denies remote user sessions (to access the server via RDP).

Note: Even if the value is 1, change it from 1 to 0 and refresh the registry. Again the change the value back from 0 to 1 and refresh the registry.

ย 4.ย The following registry location is used to enable Remote User Session on a server

ย 

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp

ย Under the ICA-Tcp key, the REG_DWORD value named fEnableWinStation should be 1 from 0 because the value data 0 denies remote user sessions (to access the server via RDP).

Note: Even if the value is 1, change it from 1 to 0 and refresh the registry. Again the change the value back from 0 to 1 and refresh the registry.

5. The following registry location, which is responsible for RDP port:

ย HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp

Under the RDP-Tcp key, the REG_DWORD value named PortNumber should be 3389 because by default, the Remote Desktop listens on port 3389 via TCP connection (to access the server via RDP).

ย Note: Open command prompt and type the below command

ย C:\telnet โ€œSERVERNAME OR IP ADDRESSโ€ 3389

ย See if it is opened!!

ย P.S: At times, this may require a restart after making these changes if it still doesnโ€™t work.

ย 6.ย The following registry location is used to enable/disable logon to a Terminal Server

ย HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

ย Under the Winlogon key, the REG_DWORD value named WinStationsDisabled should be 0 because the value data 1 denies logon to a Terminal Server via RDP.

Note: Even if the value is 0, change it from 0 to 1 and refresh the registry. Again the change the value back from 1 to 0 and refresh the registry.

What is a Queue Manager? What are the responsibilities of a Queue Manager?

Posted on Updated on

A Queue Manager or a Dispatcher is a resource who primary task is to assign the incident tickets to resources as per their skill set. Their primary role is to meet the SLA targets for an incident ticket. Below are the responsibilities of a Queue Manager:

  • Monitoring the queues and assign the incidents before missing Response time SLA
  • Tickets to be assigned with respective Support Engineer according to required skills sets
  • Follow up with engineerย for closing the tickets those are going to be SLA breached
  • Assigned the tickets which are out of scope to Service Desk/Other Teams.
  • Publishing Weekly Change Calendar
  • Daily Report on Incidents/Change/Problem tickets and SLA status
  • Daily Change schedule reminder to respective changeย assignee
  • Shift Handover to Next Queue Manager
  • Summary report on all Major incidents happen on that day
  • For high number of repeated incidents, you need to relate the incidents with Parent incident and cancel the duplicate incident by marking the parent ticket info.
  • Need to discuss with TL/Shift lead for taking action against bouncing tickets

The below are the knowledge or skills which a Queue Manager should possess in order to deliver their job.

  • SLA Metric
  • Process knowledgeย (IM/CM/PM/SR)
  • Support Scope
  • Inter team SPOC contact
  • Escalation Matrix & Entire team contacts
  • Incident Categorization
  • Entire team Skill set Matrix
  • Current Shift Roster & Oncall Resource
  • Technology specific SME for Tech assistance
  • Inter Supplier Support Scope & Queue Name
  • Inter Supplier Support SPOC & Contact Details
  • Application Owners Contact & Queue Name
  • Generating the reports fromย Ticketing Tool

How to install a memory on a Cisco UCS B200 M3

Posted on Updated on

To install a DIMM into the blade server, follow these steps:

Procedure

Step 1: Open both DIMM connector latches.

Installing DIMMs in the Blade Server
Installing DIMMs in the Blade Server

Step 2:ย Press the DIMM into its slot evenly on both ends until it clicks into place.

DIMMs are keyed, if a gentle force is not sufficient, make sure the notch on the DIMM is correctly aligned.

Note:ย Be sure that the notch in the DIMM aligns with the slot. If the notch is misaligned you may damage the DIMM, the slot, or both.

Step 3:ย Press the DIMM connector latches inward slightly to seat them fully.

Supported DIMMs

The DIMMs supported in this blade server are constantly being updated. A list of currently supported and available drives is in the specification sheets at:

http:/โ€‹/โ€‹www.cisco.com/โ€‹en/โ€‹US/โ€‹products/โ€‹ps10280/โ€‹products_โ€‹data_โ€‹sheets_โ€‹list.html

Cisco does not support third-party memory DIMMs, and in some cases their use may irreparably damage the server and require an RMA and down time.

Memory Arrangement

The blade server contains 24 DIMM slotsโ€”12 for each CPU. Each set of 12 DIMM slots is arranged into four channels, where each channel has three DIMMs.

Memory Slots within the Blade Server
Memory Slots within the Blade Server

1 Channels A-D for CPU 1 2 Channels E-H for CPU 2

DIMMs and Channels

Each channel is identified by a letterโ€”A, B, C, D for CPU1, and E, F, G, H for CPU 2. Each DIMM slot is numbered 0, 1, or 2. Note that each DIMM slot 0 is blue, each slot 1 is black, and each slot 2 is off-white or beige.

The figure below shows how DIMMs and channels are physically laid out on the blade server. The DIMM slots in the upper and lower right are associated with the second CPU (CPU shown on right in the diagram), while the DIMM slots in the upper and lower left are associated with the first CPU (CPU shown on left).

Physical representation of DIMMS and channels
Physical representation of DIMMS and channels

 

Courtesy: Cisco

Microsoft is Adding a Native SSH Client and Server to Windows

Posted on Updated on

As Microsoft has shifted towards a more customer-oriented culture, Microsoft engineers are using social networks, tech communities and direct customer feedback as an integral part on how we make decisions about future investments. A popular request the PowerShell team has received is to use Secure Shell protocol and Shell session (aka SSH) to interoperate between Windows and Linux โ€“ both Linux connecting to and managing Windows via SSH and, vice versa, Windows connecting to and managing Linux via SSH. Thus, the combination of PowerShell and SSH will deliver a robust and secure solution to automate and to remotely manage Linux and Windows systems.

SSH solutions are available today by a number ofย vendors and communities, especially in the Linux world. However, there are limited implementations customers can deploy in Windows production environments. ย After reviewing these alternatives, the PowerShell team realized the best option will be for our team to adopt an industry proven solution while providing tight integration with Windows; a solution that Microsoft will deliver in Windows while working closely with subject matter experts across the planet to build it. Based on these goals, Iโ€™m pleased to announce that the PowerShell team will support and contribute to the OpenSSH community – Very excited to work with the OpenSSH community to deliver the PowerShell and Windows SSH solution!

A follow up question the reader might have is When and How will the SSH support be available? The team is in the early planning phase, and thereโ€™re not exact days yet. However the PowerShell team will provide details in the near future on availability dates.

Finally, I’d like to share some background on todayโ€™s announcement, because this is the 3rd time the PowerShell team has attempted to support SSH.ย  The first attempts were during PowerShell V1 and V2 and were rejected.ย  Given our changes in leadership and culture, we decided to give it another try and this time, because we are able to show the clear and compelling customer value, the company is very supportive.ย  So I want to take a minute and thank all of you in the community who have been clearly and articulately making the case for why and how we should support SSH!ย  Your voices matter and we do listen.

Thank you!

Angel Calvo
Group Software Engineering Manager
PowerShell Team

 

Additional Information

For more information on SSH please go to http://www.ietf.org/rfc/rfc4251.txt

For information on OpenSSH go to: http://www.openssh.com/index.html

ESXi 6.0 and vCenter Server 6.0 launched

Posted on Updated on

ESXi 6.0 and vCenter Server 6.0 has been launched on 12th May 2015.

Whatโ€™s New in the VMware vSphereยฎ 6.0 Platform – Please checkย http://www.vmware.com/files/pdf/vsphere/VMW-WP-vSPHR-Whats-New-6-0-PLTFRM.pdf

Want to upgrade to ESXi 6.0, check the Vmware compatibility guide. http://www.vmware.com/resources/compatibility/search.php

How to fix if you are unable to upgrade existing VMware Tools in a Windows 2003 virtual machine

Posted on Updated on

As per VMware, the cause of this issue is currently unknown and is under investigation.ย  In order to help identify the cause, report this issue to VMware Support and provide answers to the following questions:

  • What version of the tools are you upgrading from?
  • What version of the tools are you upgrading to?
  • What method is being used to upgrade the tools?

In order to determine the previous versions of the VMware Tools thatย were installed on your system, open the Microsoft Windows event viewer and search for Event Source of MsiInstaller and Event ID of 1034 for more information on viewing events, see the Filter Displayed Events Tech Net article from Microsoft.

Now, toย fix this issue involvesย modifies the Windows registry. Before making any registry modifications, ensure that you have a current and valid backup of the registry and the virtual machine.

  1. Start the virtual machine and log on as the Administrator.
  2. Take a full backup of the registry prior to editing it. Do not skip this step.
  3. Open the Windows Registry editor. Click Start > Run, type regedit, and press Enter.
  4. Delete these registry keys if they exist:
    • HKEY_CLASSES_ROOT\Installer\Features05014B32081E884E91FB41199E24004
    • HKEY_CLASSES_ROOT\Installer\Products05014B32081E884E91FB41199E24004
    • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Features05014B32081E884E91FB41199E24004
    • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products05014B32081E884E91FB41199E24004
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\ComponentsB150AC107B12D11A9DD0006794C4E25
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{3B410500-1802-488E-9EF1-4B11992E0440}
    • HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.
  5. Some services might need to be removed manually from the registry. Delete these as well if they exist:
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VMTools
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VMUpgradeHelper
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VMware Physical Disk Helper Service
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmvss
  6. Search the registry for vmware and delete all associated entries.Note: On virtual machines with any other VMware products installed (for example, vCenter Server), you might not want to delete all entries. If you do have another VMware product installed, then you can skip this step if you have already removed the entries in the previous procedures.
  7. Close the registry editor.
  8. Open Windows Explorer.
  9. Delete the %ProgramFiles%\VMware\VMware Tools folder.
  10. Restart the virtual machine.
  11. Install the new version of VMware Tools.

The request failed because the remote server took too long to respond. (The command has timed out as the remote server is taking too long to respond)

Posted on Updated on

You will notice this errorย ย “The request failed because the remote server “Vcenter name / ip” took too long to respond. (The command has timed out as the remote server is taking too long to respond),ย ” while checking the storage view of a VM or DataCenter.

To solve this,ย Just type your credentials manuallyย in the vsphere client and login asย the “Use Windows Session Credentials” doesn’t work always with SSO.

Thereby be sure to follow http://kb.vmware.com/kb/2035510 when adding external domains. After that, add the trusted domains to the default domains and reorder the domains to suit your needs and save it.

 

 

 

How to monitor the Disk Command Aborts on an ESXi host

Posted on Updated on

When storage is severely overloaded, commands are aborted because the storage subsystem is taking too long to respond to the commands. The storage subsystem has not responded within an acceptable amount of time, as defined by the guest operating system. Aborted commands are a sign that the storage hardware is overloaded and unable to handle the requests in line with the host’s expectations.

The number of aborted commands can be monitored by using either vsphere client or esxtop.

  1. ย from vsphere client, monitor disk commands aborts

this one can be generated from host and clusters->Performance-> Advanced -> Switch to disk -> chart options-> commands aborted-> ok.

  1. from esxtop, monitor ABRTS/s

Open putty, login to the ESXi host, run esxtop, for the disk type u, type f to change the settings and type L to select Error stats. Press W to save it.

Once this is we can see the ABRTS/s field there which tracks the SCSI aborts, Aborts generally occur because the array takes long time to respond to commands.

Now if you are planning to deploy a monitoring tool to monitor this parameter, the threshold for ABRTS/s should be 1. This signifies number of SCSI commands aborted during the collection interval i.e. in 1 second.

DISKย ย ย ย ย ย  ABRTS/sย ย ย ย ย ย ย ย ย ย ย ย ย ย  1ย ย ย ย ย ย ย ย ย ย ย ย ย  Aborts issued by guest(VM) because storage is not responding. For Windows VMs this happens after 60 seconds by default.ย Can be caused for instance when paths failed or array is not accepting any IO for whatever reason.

However having said that the in ideal case the output of ABRTS/s should be 0, which may sometime not been observer during peak hours i.e. Backup may be running on the servers hosted on the ESXi host resulting in disk intensive workouts. This ABRTS/sย will fluctuate 0 to 0.xx in real case scenario as the storage is always overloaded during these peak hours.

How to install and configure Multipathing I/O on a computer running Windows Server 2008

Posted on Updated on

To install Multipath I/O

  1. Open Server Manager.To open Server Manager, click Start, point to Administrative Tools, and then click Server Manager.
  2. In the Features area, click Add Features.
  3. On the Select Features page of the Add Features Wizard, select Multipath I/O, and then click Next.
  4. On the Confirm Installation Selections page, click Install.
  5. When installation has completed, click Close.

To install Multipath I/O on a computer by using the Server Manager command line, complete the following steps.

To install Multipath I/O by using a command line

  1. Open a Command Prompt window with elevated privileges.Right-click the Command Prompt object on the Start menu, and then click Run as administrator.
  2. Type the following, and press ENTER.ย ServerManagerCmd.exe -install Multipath-IO
  3. When installation has completed, you can verify that Multipath I/O has installed by entering the following command and reviewing the query results in the command window. Multipath I/O should show in the list of installed packages.ย ServerManagerCmd.exe -query

IC347745[1]

Removing Multipath I/O

To remove Multipath I/O, complete the following steps.

To remove Multipath I/O

  1. Open Server Manager.To open Server Manager, click Start, point to Administrative Tools, and then click Server Manager.
  2. In the Features area, click Remove Features.
  3. On the Select Features page of the Add Features Wizard, select Multipath I/O, and then click Next.
  4. On the Confirm Installation Selections page, click Install.
  5. When installation has completed, click Close.

To remove Multipath I/O by using the Server Manager command line, complete the following steps.

To remove Multipath I/O by using a command line

  1. Open a Command Prompt window with elevated privileges.Right-click the Command Prompt object on the Start menu, and then click Run as administrator.
  2. Type the following, and press ENTER.ย ServerManagerCmd.exe -remove Multipath-IO
  3. When removal has completed, you can verify that Multipath I/O was removed by entering the following command and reviewing the query results in the command window. Multipath I/O should not be in the list of installed packages.ย ServerManagerCmd.exe -query
To claim an iSCSI-attached device for use with MPIO

Open the MPIO control panel, and then click the Discover Multi-Paths tab.
  1. Select the Add support for iSCSI devices check box, and then click Add. When prompted to restart the computer, click Yes.
  2. When the computer restarts, the MPIO Devices tab lists the additional hardware ID โ€œMSFT2005iSCSIBusType_0x9.โ€ When this hardware ID is listed, all iSCSI bus attached devices will be claimed by the Microsoft DSM.

The Performance Overview tab fails to display with the error: Navigation to the webpage was cancelled (1014454)

Posted on Updated on

There are several possible causes for this issue. Attempt each of the troubleshooting steps below in sequence, without skipping any.

  1. Confirm that the vCenter Web Management Service is running.

    To resolve this issue, connect to vCenter locally with a vSphere Client located on the vCenter Server and followStopping, starting, or restarting vCenter services (1003895).

  2. Ensure that the correct DNS settings and IP address are being used:
    1. On the vCenter Server, navigate toC:\Program Files\VMware\Infrastructure\VirtualCenter Server\extensions\com.vmware.vim.stats.report\.
    2. Openxmlย in a text editor.
    3. Edit the line<url>https://hostname:8443/statsreport/vicr.do</url>ย to use an IP address instead of an FQDN to rule out issues with DNS.
    4. Restart vCenter Web Management Service and the vCenter Server Service after making any changes to the.xmlย  Forย moreinformation, seeย Stopping, starting, or restarting vCenter services (1003895).
  3. Disable any third party web services that may be interfering with the vCenter Web Management Services.

    To confirm that a third party web service is the cause:

    1. Stop the vCenter Web Management Service. For more information, seeStopping, starting, or restarting vCenter services (1003895).
    2. Try to connect to port 8443 (the port on which the Web Management Service runs) by executing:

      telnetย IP8443

    3. If the port responds when the vCenter Web Management Service is stopped, there might be another service that is using the port. In this case, if you want to continue running the conflicting third party service, you may have to change the port that Performance Overview uses. To change the port used by Performance Overview, seeThe Performance Overview tab within vCenter Server reports the HTTP Status 404 error (1016160).
  4. Check if vCenter Server is using custom SSL certificates as a result of a recent upgrade to vCenter Server 4.0 Update 1. For more information, seeVMware vCenter Server plugins fail after adding custom SSL certificates (1017577).

Note: Additionally, you can perform these steps:

  • Disable theย proxy settingsย from the browser.

    To disable the settings:

  1. LaunchInternet
  2. Navigate toToolsย >ย Internet options.
  3. Click theConnections
  4. ClickLAN settings.
  5. Select theUse automatic configuration script
  • If youย experience this issueย on workstations external to the vCenter Server,ย try to connect to port 8443 (the port on which the Web Management Service runs) as per Step 3b. If you are unable to connect to the port,ย disable the Windowsย Firewallย on the vCenter Serverย system. For more information, see theย Microsoftย TechNet articleย I Need to Disable Windows Firewall.

Help and support service not running in Windows 2003

Posted on Updated on

To fix this:

  • Open a Command Prompt
  • Run the following commands
  • %SystemDrive%
  • CD %windir%\PCHealth\HelpCtr\Binaries
  • start /w helpsvc /svchost netsvcs /regserver /install

The service should install and start automatically.

How to Clean up the WinSxS Directory on Windows Server 2008 R2

Posted on Updated on

Prior to this we need to install Disk Cleanup on Windows 2008. Disk Cleanup is not installed by default on Windows Server 2008 R2. It is instead a component installed with the Desktop Experience feature.

To install Disk Cleanup without reboot the server – How to install Disk Cleanup without reboot the server in Window 2008

Now download the appropriate package and install the on the system.

Operating system Update
All supported x86-based versions of Windows 7
All supported x64-based versions of Windows 7
ย ย DownloadDownload
All supported x64-based versions of Windows Server 2008 R2
ย ย DownloadDownload

Looking at my Windows 2008 R2 Server with SP1 installed, according to Windows Explorer, the size of my Windows/WinSxS directory is as follows:

pic1[1]

The size of the WinSxS directory will vary by server. Some of you will have smaller WinSxS directories, some larger.

Installing the update is just like installing any other update. Just download and double-click on the .msu file:

pic2[1]

 

Now we need to run the disk cleanup wizard. Disk Cleanup option can be found under Startย –> All Programsย –> Accessoriesย –> System Tools: or go to run and type ‘cleanmgr’ to launch it.

pic8[1]

On launch, Disk Cleanup prompts for the drive you want to clean up, default drive will be C: drive

pic9[1]

After clicking Ok, a scan is performed:

pic10[1]

Several options are provided for cleanup, including a new option for Windows Update Cleanup:

pic11[1]

If you didnโ€™t launch Disk Cleanup as Administrator, at this point, youโ€™ll need to take a couple extra steps. Youโ€™ll need to click on the Clean up system files button.

3348.diskcleanup3[1]

The actual cleanup occurs during the next reboot. After the reboot, taking a look at the WinSxS directory, it has shrunk to the following:

pic12[1]

 

How to change default snapshot location in VMware ESXi 5

Posted on Updated on

Defaulty the snapshots which are taken for any virtual machine are stored with their parent in the same directory or storage. Sometimes you may run out of space and you might not be able to take anymore snapshots so in that case you can always use some other location for the storage of snapshots.

snapshot
These are the required steps to be taken toย change the default locations of all the snapshots .

NOTE: Please ensure that the vm you are working on is powered OFF.

Right Click the vm and selectย Edit Settings
Click onย Optionsย from the top TAB, selectย Generalย and open theย Configuration parameters

Add a new row with the following details

snapshot.redoNotWithParent

Save this parameter with a value “true” as shown below

Now open the CLI of the host where the vm is located

Go to the vm’s parent directory where all the vm files are stored and open the main .vmx file

As in my case

# cd /vmfs/volumes/53652b45-90f342h4-v3r3-s5dw676h5674/Windows2003
# vi Windows2003.vmx

Now add this line anywhere in the .vmx file with the path location where you want your snapshots to be stored

workingDir = “/vmfs/volumes/54332bf4-gd3bf353-g45b-g2ft353b5545/snapshots”

Save the file and exit

Now you need to reload this vm to make the changes take affect.
# vim-cmd vmsvc/getallvms | grepย Windows2003
13ย Windows2003 [iSCSI-Datastore15] Windows2003/Windows2003 win2003ย vmx-07
Here 13ย is the vm id which you can find out using the above command
# vim-cmd vmsvc/reloadย 13
Now when you take snapshots the snapshot files and vm swap files will be created in a different location.

How to redirect vm’s swap file

In case you do not want vm swap file to be redirected to another location and you want it to the same parent directory.
Add an extra parameter in the Configuration Parameter option shown above
sched.swap.dir=”<path_to_vm_directory>”
For example
/vmfs/volumes/54332bf4-gd3bf353-g45b-g2ft353b5545/vmswap

Save the settings and exit. Now each time you take snapshot the snapshot files and vm swap files will be saved at specified different location.

 

RVTools 3.7

Posted on Updated on

RVTools

RVTools is a windows .NET 2.0 application which uses the VI SDK to display information about your virtual machines and ESX hosts. Interacting with VirtualCenter 2.5, ESX Server 3.5, ESX Server 3i, VirtualCenter 4.x, ESX Server 4.x, VirtualCenter 5.0, VirtualCenter Appliance, ESX Server 5.0, VirtualCenter 5.1, ESX Server 5.1, VirtualCenter 5.5, ESX Server 5.5. RVTools is able to list information about VMs, CPU, Memory, Disks, Partitions, Network, Floppy drives, CD drives, Snapshots, VMware tools, Resource pools, Clusters, ESX hosts, HBAs, Nics, Switches, Ports, Distributed Switches, Distributed Ports, Service consoles, VM Kernels, Datastores, Multipath info and health checks. With RVTools you can disconnect the cd-rom or floppy drives from the virtual machines and RVTools is able to update the VMware Tools installed inside each virtual machine to the latest version.

Version 3.7 (March, 2015)

VI SDK reference changed from 5.0 to 5.5
Extended the timeout value from 10 to 20 minutes for really big environments
New field VM Folder on vCPU, vMemory, vDisk, vPartition, vNetwork, vFloppy, vCD, vSnapshot and vTools tabpages
On vDisk tabpage new Storage IO Allocation Information
On vHost tabpage new fields: service tag (serial #) and OEM specific string
On vNic tabpage new field: Name of (distributed) virtual switch
On vMultipath tabpage added multipath info for path 5, 6, 7 and 8
On vHealth tabpage new health check: Multipath operational state
On vHealth tabpage new health check: Virtual machine consolidation needed check
On vInfo tabpage new fields: boot options, firmware and Scheduled Hardware Upgrade Info
On statusbar last refresh date time stamp
On vhealth tabpage: Search datastore errors are now visible as health messages
You can now export the csv files separately from the command line interface (just like the xls export)
You can now set a auto refresh data interval in the preferences dialog box
All datetime columns are now formatted as yyyy/mm/dd hh:mm:ss
The export dir / filenames now have a formated datetime stamp yyyy-mm-dd_hh:mm:ss
Bug fix: on dvPort tabpage not all networks are displayed
Overall improved debug information
Download link:ย http://robware.net/index.php/register

Documentation:ย http://robware.net/download/RVTools.pdf

Installing Disk Cleanup In Windows 2008 Without Rebooting The Server

Posted on Updated on

The Disk Cleanup executable file cleanmgr.exe and the associated Disk Cleanup button are not present in Windows Serverยฎ 2008 or in Windows Serverยฎ 2008 R2 by default.ย This is by design, as the Disk Cleanup button is part of the Desktop Experience feature. In order to have Disk Cleanup button appear on a diskโ€™s Properties dialog, you will need to install the Desktop Experience feature.

So in order to use cleanmgr.exe youโ€™ll need to copy two files that are already present on the server, cleanmgr.exe and cleanmgr.exe.mui. Use the following table to locate the files for your operating system.

Windows Server 2008 R2 64 bit

C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.1.7600.16385_none_c9392808773cd7da\cleanmgr.exe

Windows Server 2008 R2ย 64-bit

C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.1.7600.16385_en-us_b9cb6194b257cc63\cleanmgr.exe.mui

Windows Server 2008 64-bit

C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.0.6001.18000_en-us_b9f50b71510436f2\cleanmgr.exe.mui

Windows Server 2008 64-bit

C:\Windows\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.0.6001.18000_none_c962d1e515e94269\cleanmgr.exe.mui

Windows Server 2008 32-bit

C:\Windows\winsxs\x86_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.0.6001.18000_en-us_5dd66fed98a6c5bc\cleanmgr.exe.mui

Windows Server 2008 32-bit

C:\Windows\winsxs\x86_microsoft-windows-cleanmgr_31bf3856ad364e35_6.0.6001.18000_none_6d4436615d8bd133\cleanmgr.exe
Once youโ€™ve located the files move them to the following locations:

1. Cleanmgr.exe should go in %systemroot%\System32

2. Cleanmgr.exe.mui should go in %systemroot%\System32\en-US

You can now launch the Disk cleanup tool by running Cleanmgr.exe from the command promptย or by clicking Start and typing Cleanmgr into the Search bar.

 

Restart the domain controller in Directory Services Restore Mode locally

Posted on Updated on

If you have physical access to a domain controller, you can restart the domain controller in Directory Services Restore Mode locally. Restarting in Directory Services Restore Mode takes the domain controller offline. In this mode, the server is not functioning as a domain controller.

When you start Windowsย Serverย 2003 in Directory Services Restore Mode, the local Administrator account is authenticated by the local Security Accounts Manager (SAM) database. Therefore, logging on requires that you use the local administrator password, not an Activeย Directory domain password. This password is set during Activeย Directory installation when you provide the password for Directory Services Restore Mode.

Administrative credentials

To perform this procedure, you must provide the Administrator password for Directory Services Restore Mode.

To restart the domain controller in Directory Services Restore Mode locally

  1. Restart the domain controller.
  2. When the screen for selecting an operating system appears, press F8.
  3. On the Windows Advanced Options menu, select Directory Services Restore Mode.
  4. When you are prompted, log on as the local administrator.

Change the static IP address of a domain controller

Posted on Updated on

Administrative Credentials

To perform this procedure, you must be a member of the Domain Admins group in the domain of the domain controller whose IP address you are changing.

To change the static IP address of a domain controller

  1. Log on locally (also known as interactively) to the system console of the domain controller whose IP address you want to change. If you are not able to log on to the domain controller by using the domain, you may have to start the domain controller in Directory Services Restore Mode (DSRM). For more information, see Restart the domain controller in Directory Services Restore Mode locally (https://lazyadminblog.com/2015/04/11/restart-the-domain-controller-in-directory-services-restore-mode-locally/).

On the desktop, right-clickย My Network Places, and then clickย Properties.

  1. In theNetwork Connectionsย dialog box, right-clickย Local Area Connection, and then clickย Properties.
  2. In theLocal Area Connection Propertiesย dialog box, double-clickย Internet Protocol (TCP/IP).
  3. In theInternet Protocol (TCP/IP) Propertiesย dialog box, in theย IP addressย box, type the new address.
  4. In theSubnet maskย box, type the subnet mask.
  5. In theDefault gatewayย box, type the default gateway.
  6. In thePreferred DNS serverย box, type the address of the DNS server that this computer contacts.
  7. In theAlternate DNS serverย box, type the address of the DNS server that this computer contacts if the preferred server is unavailable.
  8. If this domain controller uses WINS servers, clickAdvancedย and then, in theย Advanced TCP/IP Settingsย dialog box, click theย WINS
  9. If an address in the list is no longer appropriate, click the address, and then clickEdit.
  10. In theTCP/IP WINS Serverย dialog box, type the new address, and then clickย OK.
  11. Repeat steps 11 and 12 for all addresses that need to be changed, and then clickOKย twice to close theย TCP/IP WINS Serverย dialog box and theย Advanced TCP/IP Settingsย dialog box.
  12. ClickOKย to close theย Internet Protocol (TCP/IP) Propertiesย dialog box.

After you change the IP address of a domain controller, you should run theย ipconfig /registerdnsย command to register the host record andย dcdiag /fixย command to ensure that service records are appropriately registered with DNS. For more information, see Dcdiag Overview and subordinate topics for additional information about the Dcdiag tool (https://lazyadminblog.com/2015/04/11/dcdiag-overview/).

Changing the IP settings of a server does not affect the share resources or shared permissions on that server, if the name resolution structure DNS and WINS settings are correctly configured. However, if network drives or passive connections (connections that are made manually from a command prompt or run line) are mapped using the IP address, an update is required. For example, if a client computer has G: drive mapped using the following commandย net use g: \\192.168.0.199\dataย and the IP address of the server that hosts the Data shared folder is changed from 192.168.0.199 to 192.168.1.200, the new G: drive mapping command should be changed toย net use g: \\192.168.1.200\data. A better solution would be to ensure that DNS name resolution is working properly and to use the server name, as opposed to the IP address, in the command. For example, if the server name is DC1, the command to map a G: drive to the Data share on the server isย net use g: \\dc1\data. It changes only if the server name changes; it is not affected if the IP address of the server changes.

Using esxtop to identify storage performance issues for ESX / ESXi (multiple versions) (1008205)

Posted on Updated on

The interactive esxtop utility can be used to provide I/O metrics over various devices attached to a VMware ESX host.

Configuring monitoring using esxtop

ย To monitor storage performance per HBA:

  1. Start esxtop by typing esxtop at the command line.
  2. Press d to switch to disk view (HBA mode).
  3. To view the entire Device name, press SHIFT + L and enter 36 in Change the name field size.
  4. Press f to modify the fields that are displayed.
  5. Press b, c, d, e, h, and j to toggle the fields and press Enter.
  6. Pressย s and thenย 2ย to alter the update time to every 2 seconds and press Enter.
  7. See Analyzing esxtop columns for a description of relevant columns. For more information, see Interpreting esxtop Statistics.

Note: These options are available only in VMware ESX 3.5 and later.

To monitor storage performance on a per-LUN basis:

  1. Start esxtop by typing esxtop from the command line.
  2. Press u to switch to disk view (LUN mode).
  3. Press f to modify the fields that are displayed.
  4. Pressย b, c, f, and h to toggle the fields and press Enter.
  5. Press s and then 2 to alter the update time to every 2 seconds and press Enter.
  6. See Analyzing esxtop columns for a description of relevant columns. For more information, see Interpreting esxtop Statistics.

To increase the width of the device field in esxtop to show the complete naa id:

  1. Start esxtop by typing esxtop at the command line.
  2. Press u to switch to the disk device display.
  3. Press Lย to change the name field size.Note: Ensure to use uppercase L.
  4. Enter the value 36 to display the complete naa identifier.

To monitor storage performance on a per-virtual machine basis:

  1. Start esxtop by typing esxtop at the command line.
  2. Type v to switch to disk view (virtual machine mode).
  3. Press f to modify the fields that are displayed.
  4. Pressย b, d, e, h, and j to toggle the fields and press Enter.
  5. Press s and then 2 to alter the update time to every 2 seconds and press Enter.
  6. See Analyzing esxtop columns for a description of relevant columns. For more information, see Interpreting esxtop Statistics.

 

Analyzing esxtop columns

Refer to this table for relevant columns and descriptions of these values:

Column ย Description
CMDS/s This is the total amount of commands per second and includes IOPS (Input/Output Operations Per Second) and other SCSI commands such as SCSI reservations, locks, vendor string requests, unit attention commands etc.ย being sent to or coming from the device or virtual machine being monitored.In most cases, CMDS/s = IOPS unless there are a lot of metadata operations (such as SCSI reservations)
DAVG/cmd This is the average response time in milliseconds per command being sent to the device.
KAVG/cmd This is the amount of time the command spends in the VMkernel.
GAVG/cmd This is the response time as it is perceived by the guest operating system. This number is calculated with the formula: DAVG + KAVG = GAVG

These columns are for both reads and writes, whereas xAVG/rd is for reads and xAVG/wr is for writes. The combined value of these columns is the best way to monitor performance, but high read or write response time it may indicate that the read or write cache is disabled on the array. All arrays perform differently, however,ย DAVG/cmd, KAVG/cmd, and GAVG/cmd should not exceed more than 10 milliseconds (ms) for sustained periods of time.

Note: VMware ESX 3.0.x does not include direct functionality to monitor individual LUNs or virtual machines using esxtop. Inactive LUNs lower the average for DAVG/cmd, KAVG/cmd, and GAVG/cmd. These values are also visible from the vCenter Server performance charts. For more information, see theย Performance Charts section in the Basic System Administration Guide.

If you experience high latency times, investigate current performance metrics and running configuration for the switches and the SAN targets. Check for errors or logging that may suggest a delay in operations being sent to, received, and acknowledged. This includes the array’s ability to process I/O from a spindle count aspect, or the array’s ability to handle the load presented to it.

If the response time increases to over 5000 ms (or 5 seconds), VMware ESX will time out the command and abort the operation. These events are logged; abort messages and other SCSI errors can be reviewed in these logs:

  • ESX 3.5 and 4.x โ€“ /var/log/vmkernel
  • ESXi 3.5 and 4.x โ€“ /var/log/messagesย 
  • ESXi 5.x and later – /var/log/vmkernel.log

The type of storage logging you may see in these files depends on the configuration of the server. You can find the value of these optionsย by navigating toย Host > Configuration > Advanced Settings > SCSI > SCSI.Log* or SCSI.Print*.

Connecting to a virtual machine console fails with the error: The VMRC Console has Disconnected. Trying to reconnect (2050470)

Posted on Updated on

Error: The VMRC Console has Disconnected.. Trying to reconnect

If this happens, then the VM will not be reachble on the network and you cannot see black screen on the VM console.

To fix this, killย the vmware-vmrc.exe*32 service from Windows Task Manager and thenย open the console again.

From Zero to Complete IP Inventory in 5 Seconds: The Multi-Host VBScript

Posted on Updated on

Manually documenting IP addresses, MACs, and DNS settings is the definition of “busy work.” This VBScript automates the entire process. It reads a list of servers from a text file, queries each one via WMI, and builds a professional Excel report in real-time.

How to Use This Script

  1. Prepare the Input: Create a text file (e.g., servers.txt) and list your hostnames or IP addresses, one per line.
  2. Save the Script: Save the code below as IPAddressInventory.vbs.
  3. Run: Double-click the .vbs file. When prompted, provide the full path to your text file (e.g., C:\Scripts\servers.txt).
  4. Requirement: You must have Microsoft Excel installed on the machine where you run the script.

The VBScript Code

VBScript

' Save as IPAddressInventory.vbs
' Input: Text file with Hostnames/IPs
' Output: Excel Spreadsheet (IP_Addresses.xlsx)
On Error Resume Next
Const FOR_READING = 1
'--- File Input ---
strSrvListFile = InputBox ("Please enter the server list file path OR UNC file path" & vbCrLf & "Eg: C:\Scripts\server.txt" & vbCrLf & "Eg: \\servername\scripts\server.txt","File Input location")
Set objFSO = CreateObject ("Scripting.FileSystemObject")
Set objReadFile = objFSO.OpenTextFile (strSrvListFile, FOR_READING)
'--- File Output ---
strOutput = objfso.GetParentFolderName(strSrvListFile) &"\"
'--- Error Handling ---
If Err.Number <> 0 Then
WScript.Echo "Please Enter a Valid file Name"
Err.Clear
WScript.Quit
End If
'--- Excel Object Creation ---
Set objExcel = CreateObject ("Excel.application")
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add()
Set objWorksheet = objWorkbook.Worksheets("Sheet1")
x = 1
y = 1
'--- Define Headers ---
objWorksheet.Cells (x, y).value = "S.No"
objWorksheet.Cells (x, y+1).value = "Server Name"
objWorksheet.Cells (x, y+2).value = "Description"
objWorksheet.Cells (x, y+3).value = "IP_Address"
objWorksheet.Cells (x, y+4).value = "Subnet"
objWorksheet.Cells (x, y+5).value = "MACAddress"
objWorksheet.Cells (x, y+6).value = "Gateway"
objWorksheet.Cells (x, y+7).value = "Preffered DNS"
objWorksheet.Cells (x, y+8).value = "Primary DNS"
objWorksheet.Cells (x, y+9).value = "Secondary DNS"
objWorksheet.Cells (x, y+10).value = "Additional DNS 1"
objWorksheet.Cells (x, y+11).value = "Additional DNS 2"
objWorksheet.Cells (x, y+12).value = "WINS Primary"
objWorksheet.Cells (x, y+13).value = "WINS Secondary"
objWorksheet.Cells (x, y+14).value = "DNS Suffix"
objWorksheet.Cells (x, y+15).value = "DNS Suffix Order"
objWorksheet.Cells (x, y+16).value = "Remarks"
s = 1
Do Until objReadFile.AtEndOfStream
k = 0
arrComputer = objReadFile.ReadLine
strServer = Split (arrComputer, ",")
objWorksheet.Cells (x+1, y).value = s
objWorksheet.Cells (x+1, y+1).value = strServer(k)
Set objWMIService = GetObject ("winmgmts:" & "!\\" & strServer(k) & "\root\cimv2")
'--- Query Network Information ---
If Err.Number = 0 Then
WScript.Echo strServer(k) &": Inventoring"
Set colAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each objAdapter in colAdapters
objWorksheet.Cells(x+1, y+2).Value = objAdapter.Description
' IP Address Logic
If Not IsNull(objAdapter.IPAddress) Then
For i = LBound(objAdapter.IPAddress) To UBound(objAdapter.IPAddress)
If Not InStr(objAdapter.IPAddress(i),":") > "0" Then
objWorksheet.Cells(x+1, y+3).Value = objAdapter.IPAddress(i)
End If
Next
End If
' Subnet Logic
If Not IsNull(objAdapter.IPSubnet) Then
For i = LBound(objAdapter.IPSubnet) To UBound(objAdapter.IPSubnet)
If objAdapter.IPSubnet(i)<> "64" Then
objWorksheet.Cells(x+1, y+4).Value = objAdapter.IPSubnet(i)
End If
Next
End If
objWorksheet.Cells(x+1, y+5).Value = objAdapter.MACAddress
' Gateway Logic
If IsNull(objAdapter.DefaultIPGateway) Then
objWorksheet.Cells(x+1, y+6).Value = "Gateway Not Set"
Else
For i = LBound(objAdapter.DefaultIPGateway) To UBound(objAdapter.DefaultIPGateway)
objWorksheet.Cells(x+1, y+6).Value = objAdapter.DefaultIPGateway(i)
Next
End If
' DNS Logic
If IsNull(objAdapter.DNSServerSearchOrder) Then
objworksheet.Cells(x+1, y+7).Value = "DNS Not Set"
Else
For i = LBound(objAdapter.DNSServerSearchOrder) To UBound(objAdapter.DNSServerSearchOrder)
objWorksheet.Cells(x+1, y+7).Value = objAdapter.DNSServerSearchOrder(i)
y = y + 1
Next
End If
y = 1
objWorksheet.Cells(x+1, y+12).Value = objAdapter.WINSPrimaryServer
objWorksheet.Cells(x+1, y+13).Value = objAdapter.WINSSecondaryServer
objWorksheet.Cells(x+1, y+14).Value = objAdapter.DNSDomain
' Suffix Logic
If IsNull(objAdapter.DNSDomainSuffixSearchOrder) Then
objworksheet.Cells(x+1, y+14).Value = "Suffix Order NA"
Else
For i = LBound(objAdapter.DNSDomainSuffixSearchOrder) To UBound(objAdapter.DNSDomainSuffixSearchOrder)
objWorksheet.Cells(x+1, y+15).Value = objAdapter.DNSDomainSuffixSearchOrder(i)
x = x + 1
Next
x = x - 1
End If
x = x + 1
WScript.Echo strServer(k) &": Completed"
Next
Else
' Error Handling for Offline Servers
objWorksheet.Cells(x+1, y+16).Value = Err.Number & "_" & Err.Description
WScript.Echo strServer(k) &": "& Err.Description
Err.Clear
x = x + 1
End If
s = s + 1
Loop
'--- Formatting and Saving ---
Set objRange = objWorksheet.UsedRange
objRange.EntireColumn.Autofit()
objExcel.ActiveWorkbook.Saveas strOutput & "IP_Addresses.xlsx"
MsgBox "Operation Completed Successfully " ,,"IP Address"

Key Features of the Script

  • Automatic Excel Formatting: It uses UsedRange.Autofit() to ensure the data is readable as soon as the file opens.
  • WMI Integration: It queries the Win32_NetworkAdapterConfiguration class directly from the remote machine.
  • Multi-Adapter Support: If a server has multiple enabled NICs, the script loops through each to capture all configurations.
  • Remark Logging: If a machine is unreachable, the error code and description are written directly into the Excel “Remarks” column so you know which servers to check manually.

Automation: Bulk Create and Delete VM Snapshots Across Linked vCenters | LazyAdminBlog.com

Posted on Updated on

In a large environment, taking snapshots before a major patch or application update is a standard safety net. But if you have servers spread across multiple vCenters in Linked Mode (e.g., Datacenter1 and Datacenter2), clicking through the vSphere Client is a waste of time.

Today, I’m sharing a “Lazy Admin” script that allows you to bulk create, check, and remove snapshots using a simple CSV list.

Prerequisites

  • VMware PowerCLI: Ensure the PowerCLI module is installed on the machine running the script.
  • CSV Setup: Create a file named snapshot_servers.csv in C:\Temp\VMSnapshots\.

The CSV should look like this: | Host | Location | | :— | :— | | Server01 | Datacenter1 | | Server02 | Datacenter2 |


Part 1: Creating Snapshots

  1. Open PowerShell ISE with vCenter Administrator credentials.
  2. Load the functions by running the full script (provided below).
  3. Run the following command:
PowerShell
Create-VMSnapshots -SS_CSV "C:\Temp\VMSnapshots\snapshot_servers.csv" -SS_Name "Pre-Patching" -SS_Description "Requested by App Team"

The script will iterate through your CSV and create snapshots sequentially. You can monitor the progress in the vSphere Tasks console.


Part 2: Deleting Snapshots

Once your changes are verified, don’t let those snapshots linger and bloat your datastores! To remove them:

  1. Use the same snapshot_servers.csv list.
  2. Run the following command:
PowerShell
Remove-VMSnapshots -SS_CSV "C:\Temp\VMSnapshots\snapshot_servers.csv"

Note: This is a sequential script; it will wait for one snapshot removal to finish before moving to the next to avoid pinning your storage I/O.


The Script: VMSnapshots.ps1

Save this code to C:\Temp\VMSnapshots\VMSnapshots.ps1.

PowerShell
function Create-VMSnapshots {
param (
[string]$SS_CSV = $(Read-Host "Enter path to CSV"),
[string]$SS_Name = $(Read-Host "Enter name for snapshots"),
[string]$SS_Description = $(Read-Host "Enter description for snapshots")
)
# Import VMware PowerCLI Module
If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) {
import-module VMware.VimAutomation.Core
}
$Servers = Import-CSV $SS_CSV
$WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue
$EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue
ForEach($Server in $Servers){
If($Server.Location -eq 'Datacenter1'){
New-Snapshot -VM $Server.Host -Name $SS_Name -Description $SS_Description -Quiesce -Server $WLM_vCenter -WarningAction SilentlyContinue
}
ElseIf($Server.Location -eq 'Datacenter2'){
New-Snapshot -VM $Server.Host -Name $SS_Name -Description $SS_Description -Quiesce -Server $EDN_vCenter -WarningAction SilentlyContinue
}
}
}
function Check-VMSnapshots {
param (
[string]$SS_CSV = $(Read-Host "Enter path to CSV"),
[string]$SS_Name = $(Read-Host "Enter snapshot name")
)
# Import VMware PowerCLI Module
If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) {
import-module VMware.VimAutomation.Core
}
$Servers = Import-CSV $SS_CSV
$WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue
$EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue
ForEach($Server in $Servers){
If($Server.Location -eq 'Datacenter1'){
Get-Snapshot -VM $Server.Host -Name $SS_Name -Server $WLM_vCenter | Select VM, Name, @{ n="SpaceUsedGB"; e={[math]::round( $_.SizeGB )}} -WarningAction SilentlyContinue
}
ElseIf($Server.Location -eq 'Datacenter2'){
Get-Snapshot -VM $Server.Host -Name $SS_Name -Server $EDN_vCenter | Select VM, Name, @{ n="SpaceUsedGB"; e={[math]::round( $_.SizeGB )}} -WarningAction SilentlyContinue
}
}
}
function Remove-VMSnapshots {
param (
[string]$SS_CSV = $(Read-Host "Enter path to CSV")
)
# Import VMware PowerCLI Module
If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) {
import-module VMware.VimAutomation.Core
}
$Servers = Import-CSV $SS_CSV
$WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue
$EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue
ForEach($Server in $Servers){
If($Server.Location -eq 'Datacenter1'){
Get-Snapshot $Server.Host -Server $WLM_vCenter | Remove-Snapshot -Confirm:$false -WarningAction SilentlyContinue
}
ElseIf($Server.Location -eq 'Datacenter2'){
Get-Snapshot $Server.Host -Server $EDN_vCenter | Remove-Snapshot -Confirm:$false -WarningAction SilentlyContinue
}
}
}