пятница, 30 июня 2023 г.

**Identifying Computer's Disk and RAM Memory: A Comprehensive Guide**

**Introduction:**

Understanding your computer's hardware specifics, such as RAM and disk drive details, is essential for efficient system upgrades, maintenance, and troubleshooting. This need became particularly apparent to me when I recently acquired a new Intel NUC 12 Enthusiast Kit computer. I transferred my old 1TB Crucial disk to the new system and set out to document its specifications, but I quickly encountered challenges identifying some components.

Here are the specifications of my new Intel NUC 12 Enthusiast Kit computer:

OS: Windows 11 Education 64-bit

Motherboard Model: NUC12SNKi72 (U3E1)

CPU: 12th Gen Intel Core i7-12700H

Memory Size: 64 MBytes - KINGSTON

Hard Drives:
KINGSTON SKC3000D2048G (SSD/NVMe) 2TB
Crucial CT1000MX500SSD4 (SSD) SATA-III 6.0Gb/s

Graphics: AW2521HFA on Intel Arc A770M Graphics + Iris Xe Graphics

The Windows Management Instrumentation Command-line (WMIC) and third-party tools offer convenient methods to fetch this kind of information. However, I found that their efficacy varied, and each tool had its own strengths and limitations. This article delves into my experiences and findings.

**Identifying RAM and Disk Drives with WMIC:**

WMIC commands are a quick and direct way to gather hardware information:

- wmic memorychip get devicelocator, manufacturer
offers details about your RAM modules, including the slot in which each memory chip is installed and the manufacturer.


- wmic diskdrive get model, serialNumber, size, mediaType
provides the model number, serial number, size, and media type of your disk drives.





Though generally reliable, WMIC may struggle with certain SSD models, like Crucial, leading to misrepresented serial numbers.


**Analyzing Third-Party Tools:**

Third-party tools can complement WMIC commands to provide a fuller picture. The following table summarizes their performance:

The tools are sorted by their overall effectiveness in identifying the three main parameters. WMIC commands, HWiNFO64, and Speccy tied in first place with 2 out of 3. Here's a deeper dive into each tool:

- **WMIC**: Reliable for identifying RAM manufacturers and Kingston disk drives, but struggles with Crucial disk serial numbers.

- **HWiNFO64**: Accurately identifies RAM manufacturers and Kingston NVMe SSDs, but falls short with Crucial SSDs.

- **Speccy**: Exceptionally good at identifying disk drives, including Crucial models, but it doesn't identify RAM manufacturers.

- **CPUID HWMonitor**: Identifies many disk drives, including those from Kingston, but struggles with Crucial SSDs and memory manufacturers.

- **CPU-Z**: While it doesn't identify either memory manufacturers or disk drives, CPU-Z shines in providing detailed information about the system's main devices, especially the CPU.


**Conclusion:**

Determining the specifics of your computer's RAM and disk memory might present certain complexities, given the wide array of hardware and the variable effectiveness of different identification tools. However, by gaining a solid understanding of your hardware specifications, you can enhance your decision-making process concerning system upgrades, maintenance, and troubleshooting.

To help you navigate this process, the table provided offers a quick reference guide to select the tool that best suits your needs. If a comprehensive and GUI-based overview is your preference, a combination of HWiNFO64 for RAM identification, Speccy for disk drive detection, and CPU-Z for CPU information can provide a well-rounded picture of your system's components.

Exploring beyond the tools mentioned in this article can open the doors to a multitude of third-party utilities, each boasting its unique features for identifying your computer's hardware. A little research can lead you to the tools that best align with your needs and budget.

Armed with the right tools and knowledge, the task of identifying the RAM and disk memory in your computer becomes straightforward. This newfound information can serve as the linchpin for maintaining your machine's performance and efficiency.

If uncertainty about the choice of tool persists, initiating your journey with WMIC commands is a recommended step. They provide a swift and simple method for gaining basic information about your hardware. For a more in-depth understanding, consider using one of the third-party tools highlighted in this article. However, if identification challenges remain, your computer's manual or manufacturer support can serve as an invaluable resource.

This understanding of your system's specifics can streamline your troubleshooting efforts, optimize performance, and guide your future hardware decisions. So, continue to explore, learn and harness the full potential of your machine.

четверг, 8 июня 2023 г.

Dynamic menu script to run other scripts

 # Get scripts in a folder, create a GUI menu and run the chosen script

# "Path_To_Scripts_Directory\" - it's not where this launching script is located, it's where the bunch of scripts you want to create the menu from is.

$PathToScripts = "Path_To_Scripts_Directory\"

$FilesInPath = $PathToScripts+"*"

# get a list of scripts/files

$Scripts = Get-ChildItem -File $FilesInPath | sort Name

# choosing the script for run 

$SelectedScript = $Scripts.Name | OGV -Title "Menu" -PassThru

$FullPathToScript = $PathToScripts+$SelectedScript

# launching selected script

& $FullPathToScript

vCloud - Export Template to OVF

 #ScriptDescription : =Export from Template to OVF=

cls

Write-Host "Export from vCloud Template to OVF with help of vCenter" -BackgroundColor DarkRed -foreground Yellow

Write-Host "(Check lease and renew if needed)" -BackgroundColor Black

$TemplateName = ""

$DestVAppName = ""

$SubStringLength = "10"

Import-Module VMware.PowerCLI | Out-Null

# Import-Module VMware.PowerCLI 3>$null

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -confirm:$false | Out-Null

$ErrorActionPreference = 'SilentlyContinue'

$WarningActionPreference = 'SilentlyContinue'

$ErrorPreference = 'SilentlyContinue'

$WarningPreference = 'SilentlyContinue'


##== Defining general parameters ==##

[Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') > $NULL

$TemplateName = [Microsoft.VisualBasic.Interaction]::InputBox("Put Template name `n(otherwise the script will exit...)", "Template Name")

IF(-not$TemplateName){Write-Host "You did not provide Template name, the script is exiting..." -BackgroundColor Black; Break}

if  ($TemplateName.Length -gt $SubStringLength)

    # {$ShortTemplateName = $TemplateName.SubString(0,25); $DestVAppName = $ShortTemplateName+"(OVF)"}

    {$DestVAppName = ($TemplateName.SubString(0,$SubStringLength))+"(OVF)"}

else{$DestVAppName = $TemplateName+"(OVF)"}

Write-Host "Destination VApp name is '$DestVAppName'" -BackgroundColor Green

$UpperFolder = "D:\OVF"

$DestFolder = -join($UpperFolder+"\"+$DestVAppName+"\")

MD $DestFolder

$TestPath = Test-Path -Path $DestFolder

If($TestPath){Write-Host "Path '$DestFolder' exists!" -BackgroundColor Red} Else{ "Path isn't created. The script will exit..."; Break } 

##== Defining vCloud/vCenter connection parameters ==##

$vCloud = 'vCloud'

$vCenter = 'VCRD'

$UserName = $env:UserName

$SecurePass = Read-Host -AsSecureString "Please enter password for $UserName and wait..."

$ClearPass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePass))

##== Connecting to vCenter/vCloud ==##

Write-Host

Write-Host "Connecting to vCenter/vCloud" -BackgroundColor DarkRed

Disconnect-VIServer * -Confirm:$false -ErrorAction SilentlyContinue

Connect-VIServer -Server $vCenter -User $UserName -Password $ClearPass -ErrorAction SilentlyContinue | Out-Null

Write-Host You are connected to vCenter -BackgroundColor Green

Disconnect-CIServer * -Confirm:$false | Out-Null

Connect-CIServer -Server $vCloud -User $UserName -Password $ClearPass -ErrorAction SilentlyContinue | Out-Null

Write-Host "You are connected to vCloud" -BackgroundColor Green

$global:DefaultVIServers | select Name, User, Version

$global:DefaultCIServers | select Name, User, Version, Org


##== Real Work - Converting Template to vApp ==##

##==Checking Template existence

$VAppTemplateOBJ = Get-CIVAppTemplate $TemplateName

If(!$VAppTemplateOBJ){Write-Host "Template '$TemplateName' does not exists!" -BackgroundColor DarkRed; Break}

$VAppTemplateOBJ | FT Name, Status, Owner, OrgVdc, Catalog, StorageUsedGB -AutoSize

$OrgVdcOBJ = $VAppTemplateOBJ.OrgVdc

$OrgVdcName = $OrgVdcOBJ.Name

Write-Host "Defined Template name: '$TemplateName'"  -BackgroundColor Green

Write-Host "OrgVdc Name: '$OrgVdcName'" -BackgroundColor Green

Write-Host "Destination VApp name is '$DestVAppName'" -BackgroundColor Green

Write-Host "Destination Path: '$DestFolder'" -BackgroundColor Green

Write-Host

Write-Host "We are going to create a new vApp '$DestVAppName'..." -BackgroundColor Black -ForegroundColor Yellow

$NewVApp = New-CIVApp -Name $DestVAppName -OrgVdc $OrgVdcName -VAppTemplate $VAppTemplateOBJ

Write-Host "You have created a new vApp '$NewVApp'" -BackgroundColor Black -ForegroundColor Yellow

$NewVApp

Write-Host "Getting vCloud vApp properties" -BackgroundColor Green

$vAppObj = Get-CIVApp -Name $DestVAppName

$vAppObj | FT Name, Status, Org, Owner, Shared, SizeGB -AutoSize

#== Stopping the vApp (It is not nessessary because a new vApp is not running, but to be sure)

Stop-CIVApp $vAppObj -Confirm:$false

##== Converting vApp VM names to vCenter names ==##

$vAppVMObj = $vAppObj | Get-CIVM

$vAppVMsCount = $vAppVMObj.Count

Write-Host "vApp '$vAppObj' has $vAppVMsCount VMs :" -BackgroundColor Green

$vAppVMObj | FT Name, Status, CpuCount, MemoryGB, Description, GuestOSFullName, VApp -AutoSize

Write-Host "Select VMs for exporting to OVF :" -BackgroundColor Green

$vAppVMObjChosen = $vAppVMObj | OGV -PassThru

Write-Host "You selected $vAppVMObjChosen VMs"

# Action

ii $DestFolder

Write-Host "Wait for several hours until the process finish....." -ForegroundColor Green -Background DarkRed

ForEach ($CloudVM in $vAppVMObjChosen)

{

Get-Date

$vCenterVMName = (Get-View –RelatedObject $CloudVM.ExtensionData).Name

Write-Host "'$CloudVM' = '$vCenterVMName'" -BackgroundColor Green

Write-Host "We are exporting VMs to the '$DestFolder'" -BackgroundColor Green

$VMPath = -join($DestFolder+$vCenterVMName)

Export-VApp -Destination $DestFolder -VM $vCenterVMName -Format OVF

}

ii $DestFolder

Write-Host "Now I am going to remove a new vApp '$NewVApp'" -BackgroundColor Green

#Remove-CIVApp $vAppVMObj

Get-Date

VEEAM - Export Job Sessions (logs) by Keyword

 cls

Write-Host "VEEAM - Export Job Sessions by Keyword" -BackgroundColor DarkRed -ForegroundColor Yellow

Write-Host "Wait...Wait...Wait..."

Write-Host


# Define the keyword that is common to all the jobs, date and path to file

$Keyword = "DB"

$date = (Get-Date).ToString('yyyy-MM-dd')

$folderPath = "C:\Backup\"

 


# Get the date for desired days ago

$OneYearAgo = (Get-Date).AddYears(-1)

 


# Get all jobs that contain the keyword in their name

$Jobs = Get-VBRJob | Where-Object {$_.Name -like "*$Keyword*"}


# Get all sessions

$AllBackupSessions = Get-VBRBackupSession # The longest part of the script


Write-Host "I'm going to export all jobs with keyword $Keyword" -ForegroundColor Green


foreach ($Job in $Jobs) {

    $BackupSessions = ""

    $filePath = ""

    $JobName = $Job.name

    Write-Host

    Write-Host "JobName: $JobName"


    # Get all sessions for the specified job from the past specified days

    $BackupSessions = $AllBackupSessions | Where-Object {$_.JobName -eq $JobName -and $_.CreationTime -gt $OneYearAgo} | Select-Object OrigJobName, CreationTime, EndTime, Result, State, LogsSubFolder, LogName, Description


    # Export sessions to a CSV file

    $filePath = $folderPath+$JobName+"_"+$date+"."+"csv"

    $BackupSessions | Export-Csv -Path $filePath -NoTypeInformation

}


start $folderPath

Write-Host

Write-Host "END!"

VEEAM GUI - single Tape Job sessions.1.0

 cls


Write-Host "VEEAM GUI - single Tape Job sessions.1.0" -BackgroundColor DarkRed -ForegroundColor Yellow


Write-Host "Wait...Wait...Wait..."


 


# Importing necessary .NET Assembly


Add-Type -AssemblyName System.Windows.Forms


[System.Windows.Forms.Application]::EnableVisualStyles()


 


# Main Form


$MainForm = New-Object System.Windows.Forms.Form


$MainForm.Text = 'Veeam Tape Backup Job'


$MainForm.Size = New-Object System.Drawing.Size(350, 400)


$MainForm.StartPosition = 'CenterScreen'


$MainForm.TopMost = $true


 


# Prepare for CSV Export


$OutputPath = 'C:\Veeam-Tape-Logs'


if (!(Test-Path -Path $OutputPath -PathType Container)) {


    $null = New-Item -ItemType Directory -Path $OutputPath


}


 


# Fetch all tape jobs upfront


$TapeJobs = Get-VBRTapeJob


 


# GUI elements


 


# Jobs ListBox


$ListBoxJobs = New-Object System.Windows.Forms.ListBox


$ListBoxJobs.Location = New-Object System.Drawing.Point(10, 10)


$ListBoxJobs.Size = New-Object System.Drawing.Size(300, 100)


 


# Checkbox for OGV output


$CheckboxOgvOutput = New-Object System.Windows.Forms.CheckBox


$CheckboxOgvOutput.Location = New-Object System.Drawing.Point(10, 130)


$CheckboxOgvOutput.Text = 'Enable OGV Output'


$CheckboxOgvOutput.AutoSize = $true


 


# Checkbox for sending only Error output


$CheckboxOnlyError = New-Object System.Windows.Forms.CheckBox


$CheckboxOnlyError.Location = New-Object System.Drawing.Point(10, 160)


$CheckboxOnlyError.Text = 'Only send Error output'


$CheckboxOnlyError.AutoSize = $true


 


# Email Label


$LabelEmail = New-Object System.Windows.Forms.Label


$LabelEmail.Text = 'Email'


$LabelEmail.AutoSize = $true


$LabelEmail.Location = New-Object System.Drawing.Point(10, 200)


 


# Email TextBox


$TextBoxEmail = New-Object System.Windows.Forms.TextBox


$TextBoxEmail.Location = New-Object System.Drawing.Point(10, 230)


$TextBoxEmail.Width = 300


$TextBoxEmail.BackColor = 'LightGray'


 


# Checkbox to include other recipients


$CheckboxIncludeOthers = New-Object System.Windows.Forms.CheckBox


$CheckboxIncludeOthers.Location = New-Object System.Drawing.Point(10, 260)


$CheckboxIncludeOthers.Text = 'Include other recipients'


$CheckboxIncludeOthers.AutoSize = $true


 


# Export Button


$ButtonExport = New-Object System.Windows.Forms.Button


$ButtonExport.Location = New-Object System.Drawing.Point(10, 310)


$ButtonExport.Size = New-Object System.Drawing.Size(100, 30)


$ButtonExport.Text = 'Export CSV'


$ButtonExport.BackColor = 'Blue'


$ButtonExport.ForeColor = 'White'


 


# Send Mail Button


$ButtonSendMail = New-Object System.Windows.Forms.Button


$ButtonSendMail.Location = New-Object System.Drawing.Point(120, 310)


$ButtonSendMail.Size = New-Object System.Drawing.Size(100, 30)


$ButtonSendMail.Text = 'Send Mail'


$ButtonSendMail.BackColor = 'Blue'


$ButtonSendMail.ForeColor = 'White'


 


# Open CSV Folder Button


$ButtonOpenFolder = New-Object System.Windows.Forms.Button


$ButtonOpenFolder.Location = New-Object System.Drawing.Point(230, 310)


$ButtonOpenFolder.Size = New-Object System.Drawing.Size(100, 30)


$ButtonOpenFolder.Text = 'Open Folder'


$ButtonOpenFolder.BackColor = 'Blue'


$ButtonOpenFolder.ForeColor = 'White'


 


# Label for authoring information


$LabelAuthoring = New-Object System.Windows.Forms.Label


$LabelAuthoring.Text = "Created by Vladisla2000 and ChatGPT"


$LabelAuthoring.AutoSize = $true


$LabelAuthoring.Location = New-Object System.Drawing.Point(10, 360)


 


# Add controls to MainForm


$MainForm.Controls.AddRange(@($ListBoxJobs, $CheckboxOgvOutput, $CheckboxOnlyError, $LabelEmail, $TextBoxEmail, $CheckboxIncludeOthers, $ButtonExport, $ButtonSendMail, $ButtonOpenFolder, $LabelAuthoring))


 


# Fill the ListBox with job names when the MainForm is loaded


$MainForm.Add_Load({


    foreach ($Job in $TapeJobs) {


        $ListBoxJobs.Items.Add($Job.Name)


    }


})


 


# Define the action for the button click to export CSV


$ButtonExport_Click = {


    $SelectedJob = $ListBoxJobs.SelectedItem


    if ($null -ne $SelectedJob) {


        # Get job information


        $Job = $TapeJobs | Where-Object { $_.Name -eq $SelectedJob }


 


        # Define date one year ago


        $OneYearAgo = (Get-Date).AddYears(-1)


 


        # Filter backup sessions for the selected job from the last year


        $JobSessions = Get-VBRTapeBackupSession -Job $Job | Where-Object { $_.CreationTime -gt $OneYearAgo }


 


        # Prepare CSV Export


        $CsvExport = $JobSessions | ForEach-Object {


            [PSCustomObject]@{


                'JobName' = $Job.Name


                'SessionName' = $_.Name


                'Result' = $_.Result


                'CreationTime' = $_.CreationTime


            }


        }


 


        # Define the output filename to include date and hour


        $OutputFileName = "$($Job.Name)_$(Get-Date -Format "yyyyMMdd_HHmm").csv"


 


        # Export to CSV


        $CsvExport | Export-Csv -Path "$OutputPath\$OutputFileName" -NoTypeInformation


 


        # If CheckboxOgvOutput is checked, output the CSV content to Out-GridView


        if ($CheckboxOgvOutput.Checked) {


            $CsvExport | Out-GridView


        }


 


        # If CheckboxOnlyError is checked, filter the jobs with 'Failed' status


        if ($CheckboxOnlyError.Checked) {


            $CsvExport = $CsvExport | Where-Object { $_.Result -eq 'Failed' }


        }


 


        # Show Export Completed message


        [System.Windows.Forms.MessageBox]::Show("Export completed", "Information")


    } else {


        [System.Windows.Forms.MessageBox]::Show("Please select a job from the list", "Information")


    }


}


 


$ButtonExport.Add_Click($ButtonExport_Click)


 


# Define the action for the button click to send mail


$ButtonSendMail_Click = {


    # Send Email


    if ($TextBoxEmail.Text) {


        $SmtpServer = "your.smtp.server"


        $From = vladsp@gamaf.co.il


        $To = vladsp@gamaf.co.il


        $Subject = "Veeam Tape Backup Job Status"


        $Body = "Please find the attached CSV file for Veeam Tape Backup Job Status."


        $Attachment = "$OutputPath\$($ListBoxJobs.SelectedItem)_$(Get-Date -Format "yyyyMMdd_HHmm").csv"


 


        if ($CheckboxIncludeOthers.Checked) {


            $To += ",additional.email@domain.com"


        }


 


        Send-MailMessage -From $From -To $To -SmtpServer $SmtpServer -Subject $Subject -Body $Body -Attachments $Attachment


 


        # Show Email Sent message


        [System.Windows.Forms.MessageBox]::Show("Email sent", "Information")


    } else {


        [System.Windows.Forms.MessageBox]::Show("Please enter an email address", "Warning")


    }


}


 


$ButtonSendMail.Add_Click($ButtonSendMail_Click)


 


# Define the action for the button click to open the CSV folder


$ButtonOpenFolder_Click = {


    # Open the folder in Explorer


    Invoke-Item -Path $OutputPath


}


 


$ButtonOpenFolder.Add_Click($ButtonOpenFolder_Click)


 


# Show MainForm


$MainForm.ShowDialog()


 


# Dispose MainForm after use


$MainForm.Dispose()

VEEAM GUI - single Job sessions.1.0

 cls


Write-Host "VEEAM GUI - single Job sessions.1.0" -BackgroundColor DarkRed -ForegroundColor Yellow

Write-Host "Wait...Wait...Wait..."


# Importing necessary .NET Assembly

Add-Type -AssemblyName System.Windows.Forms

[System.Windows.Forms.Application]::EnableVisualStyles()


# Main Form

$MainForm = New-Object System.Windows.Forms.Form

$MainForm.Text = 'Veeam Tape Job'

$MainForm.Size = New-Object System.Drawing.Size(350, 400)

$MainForm.StartPosition = 'CenterScreen'

$MainForm.TopMost = $true


# Prepare for CSV Export

$OutputPath = 'C:\Veeam-Logs'


if (!(Test-Path -Path $OutputPath -PathType Container)) {

    $null = New-Item -ItemType Directory -Path $OutputPath

}


# Fetch all backup sessions upfront

$BackupSessions = Get-VBRBackupSession


# GUI elements


# Jobs ListBox

$ListBoxJobs = New-Object System.Windows.Forms.ListBox

$ListBoxJobs.Location = New-Object System.Drawing.Point(10, 10)

$ListBoxJobs.Size = New-Object System.Drawing.Size(300, 100)


# Checkbox for OGV output

$CheckboxOgvOutput = New-Object System.Windows.Forms.CheckBox

$CheckboxOgvOutput.Location = New-Object System.Drawing.Point(10, 130)

$CheckboxOgvOutput.Text = 'Enable OGV Output'

$CheckboxOgvOutput.AutoSize = $true


# Checkbox for sending only Error output

$CheckboxOnlyError = New-Object System.Windows.Forms.CheckBox

$CheckboxOnlyError.Location = New-Object System.Drawing.Point(10, 160)

$CheckboxOnlyError.Text = 'Only send Error output'

$CheckboxOnlyError.AutoSize = $true


# Email Label

$LabelEmail = New-Object System.Windows.Forms.Label

$LabelEmail.Text = 'Email'

$LabelEmail.AutoSize = $true

$LabelEmail.Location = New-Object System.Drawing.Point(10, 200)


# Email TextBox

$TextBoxEmail = New-Object System.Windows.Forms.TextBox

$TextBoxEmail.Location = New-Object System.Drawing.Point(10, 230)

$TextBoxEmail.Width = 300

$TextBoxEmail.BackColor = 'LightGray'


# Checkbox to include other recipients

$CheckboxIncludeOthers = New-Object System.Windows.Forms.CheckBox

$CheckboxIncludeOthers.Location = New-Object System.Drawing.Point(10, 260)

$CheckboxIncludeOthers.Text = 'Include other recipients'

$CheckboxIncludeOthers.AutoSize = $true


# Export Button

$ButtonExport = New-Object System.Windows.Forms.Button

$ButtonExport.Location = New-Object System.Drawing.Point(10, 310)

$ButtonExport.Size = New-Object System.Drawing.Size(100, 30)

$ButtonExport.Text = 'Export CSV'

$ButtonExport.BackColor = 'Blue'

$ButtonExport.ForeColor = 'White'


# Send Mail Button

$ButtonSendMail = New-Object System.Windows.Forms.Button

$ButtonSendMail.Location = New-Object System.Drawing.Point(120, 310)

$ButtonSendMail.Size = New-Object System.Drawing.Size(100, 30)

$ButtonSendMail.Text = 'Send Mail'

$ButtonSendMail.BackColor = 'Blue'

$ButtonSendMail.ForeColor = 'White'


# Open CSV Folder Button

$ButtonOpenFolder = New-Object System.Windows.Forms.Button

$ButtonOpenFolder.Location = New-Object System.Drawing.Point(230, 310)

$ButtonOpenFolder.Size = New-Object System.Drawing.Size(100, 30)

$ButtonOpenFolder.Text = 'Open Folder'

$ButtonOpenFolder.BackColor = 'Blue'

$ButtonOpenFolder.ForeColor = 'White'


# Label for authoring information

$LabelAuthoring = New-Object System.Windows.Forms.Label

$LabelAuthoring.Text = "Created by Vladisla2000 and ChatGPT"

$LabelAuthoring.AutoSize = $true

$LabelAuthoring.Location = New-Object System.Drawing.Point(10, 360)


# Progress Bar

$ProgressBar = New-Object System.Windows.Forms.ProgressBar

$ProgressBar.Location = New-Object System.Drawing.Point(10, 290)

$ProgressBar.Size = New-Object System.Drawing.Size(320, 15)

$ProgressBar.Style = "Continuous"

$ProgressBar.Visible = $false


# Add controls to MainForm

$MainForm.Controls.AddRange(@($ListBoxJobs, $CheckboxOgvOutput, $CheckboxOnlyError, $LabelEmail, $TextBoxEmail, $CheckboxIncludeOthers, $ButtonExport, $ButtonSendMail, $ButtonOpenFolder, $LabelAuthoring, $ProgressBar))


# Fill the ListBox with job names when the MainForm is loaded

$MainForm.Add_Load({

    $Jobs = Get-VBRJob

    foreach ($Job in $Jobs) {

        $ListBoxJobs.Items.Add($Job.Name)

    }

})


# Define the action for the button click to export CSV

$ButtonExport_Click = {

    $SelectedJob = $ListBoxJobs.SelectedItem

    if ($null -ne $SelectedJob) {


        # Get job information

        $Job = Get-VBRJob | Where-Object { $_.Name -eq $SelectedJob }


        # Define date one year ago

        $OneYearAgo = (Get-Date).AddYears(-1)


        # Filter job sessions for the selected job from the last year

        $JobSessions = $BackupSessions | Where-Object { $_.JobId -eq $Job.Id -and $_.CreationTime -gt $OneYearAgo }


        # Prepare CSV Export

        $CsvExport = $JobSessions | ForEach-Object {

            [PSCustomObject]@{

                'JobName' = $Job.Name

                'SessionName' = $_.Name

                'Result' = $_.Result

                'CreationTime' = $_.CreationTime

            }

        }


        # Define the output filename to include date and hour

        $OutputFileName = "$($Job.Name)_$(Get-Date -Format "yyyyMMdd_HHmm").csv"


        # Export to CSV

        $CsvExport | Export-Csv -Path "$OutputPath\$OutputFileName" -NoTypeInformation


        # If CheckboxOgvOutput is checked, output the CSV content to Out-GridView

        if ($CheckboxOgvOutput.Checked) {


            $CsvExport | Out-GridView

        }


        # If CheckboxOnlyError is checked, filter the jobs with 'Failed' status

        if ($CheckboxOnlyError.Checked) {

            $CsvExport = $CsvExport | Where-Object { $_.Result -eq 'Failed' }

        }


        # Show Export Completed message

        [System.Windows.Forms.MessageBox]::Show("Export completed", "Information")


    } else {

        [System.Windows.Forms.MessageBox]::Show("Please select a job from the list", "Information")

    }

}


$ButtonExport.Add_Click($ButtonExport_Click)


# Define the action for the button click to send mail

$ButtonSendMail_Click = {

    # Send Email

    if ($TextBoxEmail.Text) {

        $SmtpServer = "your.smtp.server"

        $From = vladsp@gamaf.co.il

        $To = vladsp@gamaf.co.il

        $Subject = "Veeam Backup Job Status"

        $Body = "Please find the attached CSV file for Veeam Backup Job Status."

        $Attachment = "$OutputPath\$($ListBoxJobs.SelectedItem)_$(Get-Date -Format "yyyyMMdd_HHmm").csv"


        if ($CheckboxIncludeOthers.Checked) {

            $To += ",additional.email@domain.com"

        }


        Send-MailMessage -From $From -To $To -SmtpServer $SmtpServer -Subject $Subject -Body $Body -Attachments $Attachment


        # Show Email Sent message

        [System.Windows.Forms.MessageBox]::Show("Email sent", "Information")


    } else {

        [System.Windows.Forms.MessageBox]::Show("Please enter an email address", "Warning")

    }

}


$ButtonSendMail.Add_Click($ButtonSendMail_Click)


# Define the action for the button click to open the CSV folder

$ButtonOpenFolder_Click = {

    # Open the folder in Explorer

    Invoke-Item -Path $OutputPath

}

$ButtonOpenFolder.Add_Click($ButtonOpenFolder_Click)


# Show MainForm

$MainForm.ShowDialog()

# Dispose MainForm after use

$MainForm.Dispose()