Skip to content

Instantly share code, notes, and snippets.

@marckean
Last active November 25, 2019 04:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marckean/04ff8be97cf9ff07fc718ce502f4de4d to your computer and use it in GitHub Desktop.
Save marckean/04ff8be97cf9ff07fc718ce502f4de4d to your computer and use it in GitHub Desktop.
<#
Written with version 2.8.0 of the Azure PowerShell Module
available from here https://github.com/Azure/azure-powershell/releases/tag/v2.8.0-October2019
or run: Install-Module -Name Az -RequiredVersion 2.8.0 -AllowClobber
Migration instructions Azure.RM to Az - https://azure.microsoft.com/en-au/blog/how-to-migrate-from-azurerm-to-az-in-azure-powershell/
#>
#$resourceGroupName = Read-Host -Prompt "Enter the Resource Group name"
Add-AzAccount
function Out-GridView {
<#
.SYNOPSIS
Send objects to Out-Gridview in Windows PowerShell
.DESCRIPTION
This command is intended as a workaround for PowerShell Core running on a Windows platform, presumably Windows 10. PowerShell Core does not support all of the .NET Framework which means some commands like Out-Gridview are not supported. However, on a Windows desktop you are most likely running Windows PowerShell side by side with PowerShell Core. This command is designed to take objects from a PowerShell expression and send it to an instance of Windows PowerShell running Out-Gridview. You can specify a title and pass objects back to your PowerShell Core session. Note that passed objects will be deserialized versions of the original objects.
.PARAMETER Title
Specify a Title for the Out-Gridview window
.PARAMETER Passthru
Pass selected objects from Out-Gridview back to your PowerShell Core session.
.EXAMPLE
PS C:\> get-childitem c:\scripts\*.ps1 | Send-ToPSGridview -title "My Scripts"
Press Enter to continue...:
Display all ps1 files in Out-Gridview. You must press Enter to continue.
.EXAMPLE
PS C:\> get-service | where status -eq 'running' | Send-ToPSGridView -Passthru | Restart-service -PassThru
Press Enter to continue...:
Status Name DisplayName
------ ---- -----------
Running BluetoothUserSe... Bluetooth User Support Service_17b710
Running Audiosrv Windows Audio
Get all running services and pipe to Out-Gridview where you can select services which will be restarted.
.EXAMPLE
PS C:\> $val = 1..10 | Send-ToPSGridView -Title "Select some numbers" -Passthru
Press Enter to continue...:
PS C:\> $val
4
8
6
PS C:\> $val | Measure-Object -sum
Count : 3
Average :
Sum : 18
Maximum :
Minimum :
StandardDeviation :
Property :
Send the numbers 1 to 10 to Out-Gridview where you can select a few. The results are saved to a variable in the PowerShell Core session where you can use them.
.INPUTS
System.Object
.OUTPUTS
None, Deserialized.System.Object[]
.NOTES
Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
#>
[cmdletbinding()]
[alias("ogv")]
[OutputType("None", "Deserialized.System.Object[]")]
Param(
[Parameter(Position = 0, ValueFromPipeline, Mandatory)]
[ValidateNotNullOrEmpty()]
[object[]]$InputObject,
[ValidateNotNullOrEmpty()]
[string]$Title = "Out-GridView",
[switch]$Passthru
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
#validate running on a Windows platform`
if ($PSVersionTable.Platform -ne 'Win32NT') {
Throw "This command requires a Windows platform with a graphical operating system like Windows 10."
}
#initialize an array to hold pipelined objects
$data = @()
#save foreground color
$fg = $host.ui.RawUI.ForegroundColor
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding object"
$data += $InputObject
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Creating a temporary xml file with the data"
$tempFile = Join-Path -path $env:temp -ChildPath ogvTemp.xml
$data | Export-Clixml -Path $tempFile
Write-Verbose "[$((Get-Date).TimeofDay) END ] Starting up a PowerShell.exe instance"
PowerShell.exe -nologo -noprofile -command {
param([string]$Path, [string]$Title = "Out-Gridview", [bool]$Passthru)
Import-Clixml -Path $path | Out-Gridview -title $Title -passthru:$Passthru
#a pause is required because if you don't use -Passthru the command will automatically complete and close
$host.ui.RawUI.ForegroundColor = "yellow"
Pause
} -args $tempFile, $Title, ($passthru -as [bool])
if (Test-Path -Path $tempFile) {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Removing $tempFile"
Remove-Item -Path $tempFile
}
#restore foreground color
$host.ui.RawUI.ForegroundColor = $fg
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Send-ToPSGridView
#Set-AzContext -SubscriptionId "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
# Select subscription
$SubscriptionList = Get-AzSubscription
$Subscription = ($SubscriptionList | Out-GridView -Title "Choose a Source Subscription ..." -PassThru)
Select-AzSubscription -Subscription $Subscription
##########################################################################################
####################### Select Source Virtual Machine ############################
##########################################################################################
#region Select Azure Source Virtual Machine | @marckean
cls
write-host -nonewline "`n`tIn subscription... " -ForegroundColor Yellow; `
write-host -nonewline $Subscription.Name`n -ForegroundColor Green;
write-host -nonewline "`n`tPlease choose a " -ForegroundColor Yellow; `
write-host -nonewline "Virtual Machine " -ForegroundColor Green
start-sleep -seconds 1
# Get Virtual Machines that contain Managed Disks only - either as an OS Disk or as a Data Disk
<#$VirtualMachines = Find-AzResource -ExpandProperties -ResourceType 'Microsoft.Compute/virtualMachines' |
? {$_.Properties.storageProfile.osDisk.managedDisk -or $_.Properties.storageProfile.dataDisks.managedDisk}#>
$VirtualMachines = Get-AzVM | ? { $_.storageProfile.osDisk.managedDisk -or $_.storageProfile.dataDisks.managedDisk } | select *
$SourceVM = ($VirtualMachines | Out-GridView -Title "Select a source Virtual Machine ..." -PassThru)
#$SourceVM = Get-AzResource -ResourceGroupName $SourceVM.ResourceGroupName -ResourceType $SourceVM.Type -ApiVersion 2019-08-01 | select * -ExpandProperties
write-host -nonewline "`n`tYou selected this Virtual Machine: " -ForegroundColor Yellow; `
write-host -nonewline $SourceVM.name`n -ForegroundColor Green; `
start-sleep -seconds 3
#endregion
# Get the details of the VM to be removed
$VM = Get-AzVM -ResourceGroupName $sourcevm.ResourceGroupName -Name $sourcevm.Name
##########################################################################################
##################### Export the JSON template for the VM ########################
##########################################################################################
# Build the JSON paths
#$jsonResourceGroupName = "$env:TEMP\RG" + [DateTime]::Now.ToString("yyyyMMddHHmmss") + ".json"
#$jsonResourceName = "$env:TEMP\R" + [DateTime]::Now.ToString("yyyyMMddHHmmss") + ".json"
$jsonResourceName = "$env:TEMP\R_" + $VM.Name + ".json"
# Export Resource Group to JSON
#Export-AzResourceGroup -ResourceGroupName $ResourceGroupName -Path $jsonResourceGroupName -IncludeParameterDefaultValue
# Export Resource to JSON
$resource = Get-AzResource `
-ResourceGroupName $vm.ResourceGroupName `
-ResourceName $vm.Name `
-ResourceType $vm.Type
Export-AzResourceGroup `
-ResourceGroupName $resource.ResourceGroupName `
-Resource $resource.ResourceId -Path $jsonResourceName -IncludeParameterDefaultValue
##########################################################################################
############# Remove the the nominated VM, just the VM resource only #################
##########################################################################################
# Remove the original VM, don't worry, it's just the compute, not the compute('r'), no disks will be hurt in the process
Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force -ErrorAction SilentlyContinue
Remove-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force
##########################################################################################
############ JSON template massaging, ready for redeployment of the VM ###############
##########################################################################################
<#
If you want to create virtual machines from existing disks,
remove the imageReference and the osProfile elements and define these disk settings
https://docs.microsoft.com/en-us/azure/virtual-machines/windows/template-description
#>
# Convert JSON content to a PowerShell object to make editing slightly easier
$jsonResourceNameObject = (Get-Content $jsonResourceName -Raw) | ConvertFrom-Json
# remove osProfile
($jsonResourceNameObject.resources.Properties).psobject.Properties.Remove('osProfile')
# remove imageReference
($jsonResourceNameObject.resources.Properties.storageProfile).psobject.Properties.Remove('imageReference')
# Spin the JSON PowerShell Object back into JSON format
$json = $jsonResourceNameObject | ConvertTo-Json -Depth 100
##########################################################
# Further massaging the JSON template
$searchText1 = '"createOption": "FromImage"'
$replaceText1 = '"createOption": "Attach"'
$searchText2 = '"createOption": "Empty"'
$replaceText2 = '"createOption": "Attach"'
$content = $json -replace $searchText1, $replaceText1 `
-replace $searchText2, $replaceText2
[io.file]::writealltext($jsonResourceName, $content)
##########################################################################################
################################ Deploy the VM again #################################
##########################################################################################
# Deploy the VM again
New-AzResourceGroupDeployment -ResourceGroupName $vm.ResourceGroupName -TemplateFile $jsonResourceName
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment