Merge pull request 'Merging dev with master' (#7) from dev into master
Reviewed-on: ofilter/Hyperv_PS_testing#7
This commit is contained in:
commit
dadd7f7259
13
Notes.md
13
Notes.md
@ -213,4 +213,15 @@ Get-VM -ComputerName Server1
|
||||
|
||||
```powershell
|
||||
Connect-VIServer
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## Snapshot
|
||||
|
||||
https://developer.vmware.com/docs/powercli/latest/products/vmwarevsphereandvsan/categories/snapshot/
|
||||
|
||||
Find hosts, iterate with domains?
|
||||
|
||||
$Hostname+.domain.dom
|
||||
|
||||
https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/get-snapshot/#Default
|
||||
|
@ -1,50 +1,135 @@
|
||||
# Author: Oriol Filter
|
||||
# Date: 08/04/2022
|
||||
# Date: 22/05/2022
|
||||
|
||||
|
||||
## Vars
|
||||
|
||||
$DebugPreference = "Continue"
|
||||
$ErrorActionPreference = "Stop"
|
||||
$SCRIPT_PATH=$PSScriptRoot
|
||||
$HYPERV_FILE = "$SCRIPT_PATH/hyperv_list.txt"
|
||||
$SCVMM_FILE = "$SCRIPT_PATH/hyperv_list.txt"
|
||||
$HOSTS_FILE = "$SCRIPT_PATH/hosts.txt"
|
||||
## Objects
|
||||
|
||||
### Disable Participation messages
|
||||
#Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false -Confirm:$false
|
||||
#Set-PowerCLIConfiguration -Scope User -InvalidCertificateAction Ignore -Confirm:$false
|
||||
#Set-PowerCLIConfiguration -Scope User -DefaultVIServerMode Multiple -Confirm:$false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Add Vhost objects for each type of server
|
||||
class VirtualVM{
|
||||
[VirtualizationServer]$__ServerObject
|
||||
class _Generic_VirtualMachine
|
||||
{
|
||||
[Object]$__ServerObject
|
||||
[Array]$__Snapshots=@()
|
||||
[Object]$__VMObject
|
||||
[VirtualizationServer]Get_ServerObject(){
|
||||
[Object]Get_ServerObject()
|
||||
{
|
||||
return $this.__ServerObject
|
||||
}
|
||||
Set_ServerObject([VirtualizationServer] $Server){
|
||||
[VirtualizationServer] $this.__ServerObject=$Server
|
||||
Set_ServerObject([Object] $Server)
|
||||
{
|
||||
[Object] $this.__ServerObject=$Server
|
||||
}
|
||||
Set_VMObject([Object] $object){
|
||||
Set_VMObject([Object] $object)
|
||||
{
|
||||
$this.__VMObject=$object
|
||||
}
|
||||
[Object]Get_VMObject(){
|
||||
[Object]Get_VMObject()
|
||||
{
|
||||
return $this.__VMObject.PowerState
|
||||
}
|
||||
|
||||
[String]Get_Name(){
|
||||
return $this.__ServerObject.Name
|
||||
[bool]__Get_Name()
|
||||
{
|
||||
$type=$this.GetType().BaseType
|
||||
Write-Warning "Get_Name not implemented in type $type"
|
||||
return $false
|
||||
}
|
||||
[bool]Get_Is_Running(){
|
||||
return @{PoweredOn=$true;PoweredOff=$false}[$this.__VMObject.PowerState]
|
||||
[String]Get_Name()
|
||||
{
|
||||
return $this.__Get_Name()
|
||||
}
|
||||
[bool]__Get_Is_Running()
|
||||
{
|
||||
$type=$this.GetType().BaseType
|
||||
Write-Warning "Get_Is_Running not implemented in type $type"
|
||||
return $false
|
||||
}
|
||||
[bool]Get_Is_Running()
|
||||
{
|
||||
return $this.__Get_Is_Running()
|
||||
}
|
||||
[Array]__Get_All_Snapshots()
|
||||
{
|
||||
$type=$this.GetType().BaseType
|
||||
Write-Warning "Get_All_Snapshots not implemented in type $type"
|
||||
return $null
|
||||
}
|
||||
[Array]Get_All_Snapshots()
|
||||
{
|
||||
return $this.__Get_Snapshots
|
||||
}
|
||||
__Load_Snapshots(){
|
||||
$type=$this.GetType().BaseType
|
||||
Write-Warning "Load_Snapshots not implemented in type $type"
|
||||
}
|
||||
Load_Snapshots(){
|
||||
$snapshots=$this.__Load_Snapshots()
|
||||
if ($snapshots){$this.__Snapshots=$snapshots}
|
||||
[String]::Format("Loaded {1} Snapshots from the VM: '{0}' at {2}",$this.Get_Name(),$this.__Snapshots.Length,$this.url) | Write-Debug
|
||||
}
|
||||
[Object]__Get_Last_Snapshot(){
|
||||
if ($this.__Snapshots.Lenght -lt 1){
|
||||
Write-Warning "No Snapshots where found, did they where loaded?"
|
||||
}
|
||||
return $this.__Snapshots[0]
|
||||
}
|
||||
[Object]Get_Last_Snapshot()
|
||||
{
|
||||
return $this.Get_Last_Snapshot()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class SCVMM_VM:VirtualVM{
|
||||
class VM_SCVMM:_Generic_VirtualMachine
|
||||
{
|
||||
[String]__Get_Name()
|
||||
{
|
||||
return $this.__ServerObject.Name
|
||||
}
|
||||
[bool]__Get_Is_Running()
|
||||
{
|
||||
return @{"PoweredOn"=$true;"PoweredOff"=$false}[$this.__VMObject.VirtualMachineState]
|
||||
}
|
||||
__Load_Snapshots(){
|
||||
Get-SCVMCheckpoint -VM $this.Get_Name() # -VMMServer $this.__ServerObject.url
|
||||
}
|
||||
|
||||
#Get-SCVMCheckpoint
|
||||
}
|
||||
|
||||
class VirtualizationServer {
|
||||
[int]$port=8100
|
||||
class VM_vSphere:_Generic_VirtualMachine
|
||||
{
|
||||
[String]
|
||||
__Get_Name()
|
||||
{
|
||||
return $this.__ServerObject.Name
|
||||
}
|
||||
[bool]
|
||||
__Get_Is_Running()
|
||||
{
|
||||
return @{ "PoweredOn" = $true; "PoweredOff" = $false }[$this.__VMObject.PowerState]
|
||||
}
|
||||
__Load_Snapshots(){
|
||||
Get-Snapshot -VM $this.Get_Name() # -VIServer $this.__ServerObject.url
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualizationServer
|
||||
{
|
||||
# The fuck does all this garbage
|
||||
# [_Generic_VirtualMachine]$__vm_obj=[_Generic_VirtualMachine]
|
||||
[int]$port=""
|
||||
[string]$url=""
|
||||
[Array] $__host_list=@()
|
||||
# [Boolean] _FindHost ($vname) {
|
||||
# $type=$this.GetType().BaseType
|
||||
# Write-Host "Find Host not implemented in type $type"
|
||||
@ -53,6 +138,12 @@ class VirtualizationServer {
|
||||
# [Boolean] FindHost ($vname) {
|
||||
# return $this._FindHost($vname)
|
||||
# }
|
||||
# [_Generic_VirtualMachine]__create_vm([Object]$item){
|
||||
# [_Generic_VirtualMachine]$new_vm=$this.__vm_obj::new()
|
||||
# $new_vm.__ServerObject=$this
|
||||
# $new_vm.__VMObject=$item
|
||||
# return $new_vm
|
||||
# }
|
||||
|
||||
__load_hosts(){
|
||||
$type=$this.GetType().BaseType
|
||||
@ -60,45 +151,40 @@ class VirtualizationServer {
|
||||
}
|
||||
|
||||
load_hosts(){
|
||||
[String]::Format("Loading VM from: {0}",$this.url) | Write-Debug
|
||||
$this.__host_list=@()
|
||||
[String]::Format("Loading VM from: {0}",$this.url) | Write-Debug
|
||||
$this.__load_hosts()
|
||||
[String]::Format("Loaded {1} VM from: {0}",$this.url,$this.__host_list.Length) | Write-Debug
|
||||
}
|
||||
|
||||
[Array] $__host_list=@()
|
||||
[Array] get_host_list(){
|
||||
return $this.__host_list
|
||||
}
|
||||
|
||||
[Boolean] __check_login(){
|
||||
$type=$this.GetType().BaseType
|
||||
Write-Warning "Check_login not implemented in type $type"
|
||||
return $false
|
||||
}
|
||||
|
||||
[Boolean] check_login(){
|
||||
Invoke-Command -ComputerName $this.url { $true }
|
||||
return $this.check_login()
|
||||
[String]::Format("Attempting to login into the server {0}",$this.url) | Write-Debug
|
||||
# Invoke-Command -ComputerName $this.url { $true }
|
||||
$result=$this.__check_login()
|
||||
return $result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SystemCenterVirtualMachineManager: VirtualizationServer {
|
||||
__load_hosts(){
|
||||
Get-SCVMMServer -ComputerName $this.url
|
||||
$list = Get-SCVirtualMachine
|
||||
$this.__host_list=$list
|
||||
# [string]::Format("Loaded {0} VM from {1}",$list.Lenght,$this.url) | Write-Debug
|
||||
}
|
||||
[Boolean] __check_login($url){
|
||||
class HypervisorServer: VirtualizationServer
|
||||
{
|
||||
[Boolean] __check_login()
|
||||
{
|
||||
$result=Invoke-Command -ComputerName $this.url { $true }
|
||||
$status_message = "OK"
|
||||
return $result
|
||||
}
|
||||
}
|
||||
class HypervisorServer: VirtualizationServer{
|
||||
[Boolean] __log_in($url){
|
||||
$result=Invoke-Command -ComputerName $this.url { $true }
|
||||
$status_message = "OK"
|
||||
return $result
|
||||
}
|
||||
# Lacks get VM
|
||||
#
|
||||
# [Boolean] _FindHost ($vname) {
|
||||
# $result=$false
|
||||
# try
|
||||
@ -116,28 +202,54 @@ class HypervisorServer: VirtualizationServer{
|
||||
# return $result
|
||||
# }
|
||||
}
|
||||
class VMWareServer: VirtualizationServer{}
|
||||
|
||||
class VirtualizerManager{
|
||||
class SystemCenterVirtualMachineManager: HypervisorServer
|
||||
{
|
||||
__load_hosts()
|
||||
{
|
||||
# Get-SCVMMServer -ComputerName $this.url
|
||||
$list = Get-SCVirtualMachine -VMMServer $this.url
|
||||
$this.__host_list=$list
|
||||
}
|
||||
}
|
||||
|
||||
class vSphereServer: VirtualizationServer
|
||||
{
|
||||
__load_hosts()
|
||||
{
|
||||
# Connect-VIServer -Server $this.url
|
||||
$list = VMware.VimAutomation.Core\Get-VM -Server $this.url
|
||||
# Hyper-V\Get-VM
|
||||
$this.__host_list=$list
|
||||
}
|
||||
[Boolean] __check_login()
|
||||
{
|
||||
Connect-VIServer -Server $this.url
|
||||
$result=$?
|
||||
# Disconnect-VIServer -Server $this.url
|
||||
return $result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class VirtualizerMiddleware{
|
||||
class VirtualizerAssistant
|
||||
{
|
||||
[Array]$__connected_servers=@()
|
||||
[Hashtable]$__found_host_dict=@{}
|
||||
[Boolean] __log_in($url){
|
||||
[String]::Format("-- {0}:",$url) | Write-Host
|
||||
$status_message=""
|
||||
[Boolean] __log_in($server){
|
||||
[String]::Format("-- {0}:",$server.url) | Write-Host
|
||||
$result=$false
|
||||
try {
|
||||
$result=Invoke-Command -ComputerName $url { $true }
|
||||
$result=$server.check_login()
|
||||
# $
|
||||
# $result=Invoke-Command -ComputerName $server.url { $true }
|
||||
}
|
||||
catch [System.Management.Automation.Remoting.PSRemotingTransportException] {
|
||||
[String]::Format("Failed to log in to URL: {0}",$url) | Write-Warning
|
||||
[String]::Format("Failed to log in to URL: {0}",$server.url) | Write-Warning
|
||||
[String]::Format("{0}",$Error[0]) | Write-Debug
|
||||
}
|
||||
finally {
|
||||
$message = [string]::Format(">>`tStatus {0}",@("NotOK","OK")[$result])
|
||||
$message = [string]::Format(">>`tStatus {0}`n",@("NotOK","OK")[$result])
|
||||
Write-Host $message
|
||||
}
|
||||
return $result
|
||||
@ -146,12 +258,12 @@ class VirtualizerMiddleware{
|
||||
|
||||
append_session($type,$url)
|
||||
{
|
||||
$type.GetType().IsValueType
|
||||
$result = $this.__log_in($url)
|
||||
# $type.GetType().IsValueType
|
||||
$server=$type::new()
|
||||
$server.url=$url
|
||||
$result = $this.__log_in($server)
|
||||
if ($result)
|
||||
{
|
||||
$server=$type::new()
|
||||
$server.url=$url
|
||||
$this.__connected_servers+=$server
|
||||
}
|
||||
}
|
||||
@ -160,6 +272,7 @@ class VirtualizerMiddleware{
|
||||
}
|
||||
|
||||
load_hosts() {
|
||||
# Downloads all the VM information from the Connected Servers
|
||||
$this.__found_host_dict=@{}
|
||||
for ($num = 0 ; $num -le $this.__connected_servers.Length -1 ; $num++){
|
||||
$server = $this.__connected_servers[$num]
|
||||
@ -192,7 +305,6 @@ class VirtualizerMiddleware{
|
||||
foreach ($entry_from_dict in $entry_from_list.GetEnumerator())
|
||||
{
|
||||
$server_location = $entry_from_dict.Name
|
||||
$vm = $entry_from_dict.Value
|
||||
[String]::Format("`t`tFound in {0}", $server_location) | Write-Host
|
||||
}
|
||||
Write-Host "`-----------`n"
|
||||
@ -201,7 +313,6 @@ class VirtualizerMiddleware{
|
||||
[String]::Format("`----------- Couldn't be found`n") | Write-Host
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
# find_host($vname){
|
||||
# $hostlist=$vname
|
||||
@ -219,51 +330,161 @@ class VirtualizerMiddleware{
|
||||
# }
|
||||
}
|
||||
|
||||
function Get-Hosts-From-File($filepath)
|
||||
{
|
||||
## In a future use a yaml as a .conf (with the hyperv and vmware listed)
|
||||
$file_content = Get-Content "$filepath"
|
||||
$splitted_file_content = $file_content.Split()
|
||||
$host_array=@()
|
||||
foreach ($hostname in $splitted_file_content)
|
||||
{
|
||||
if ($hostname)
|
||||
{
|
||||
$host_array+=$hostname
|
||||
|
||||
#Used to store the config and given an assisant object attempts to log in
|
||||
class Config{
|
||||
$_SCRIPT_PATH = ""
|
||||
$_HYPERV_FILE = ""
|
||||
$_SCVMM_FILE = ""
|
||||
$_VSPHERE_FILE = ""
|
||||
$_HOSTS_FILE = ""
|
||||
Config(){
|
||||
$this._SCRIPT_PATH = $PSScriptRoot
|
||||
$this._HYPERV_FILE = [String]::Format("{0}/hyperv_list.txt",$this._SCRIPT_PATH)
|
||||
$this._SCVMM_FILE = [String]::Format("{0}/scvmm_list.txt",$this._SCRIPT_PATH)
|
||||
$this._VSPHERE_FILE = [String]::Format("{0}/vsphere_list.txt",$this._SCRIPT_PATH)
|
||||
$this._HOSTS_FILE = [String]::Format("{0}/hosts.txt",$this._SCRIPT_PATH)
|
||||
}
|
||||
Load_Hyperv([VirtualizerAssistant] $assistant) {
|
||||
$hyperv_urls = $this._Get_Hosts_From_File($this._HYPERV_FILE)
|
||||
foreach ($url in $hyperv_urls) {
|
||||
$assistant.append_session([HypervisorServer], $url)
|
||||
}
|
||||
}
|
||||
return $host_array
|
||||
|
||||
Load_Scvmm([VirtualizerAssistant] $assistant) {
|
||||
$hyperv_urls = $this._Get_Hosts_From_File($this._SCVMM_FILE)
|
||||
foreach ($url in $hyperv_urls) {
|
||||
$assistant.append_session([SystemCenterVirtualMachineManager], $url)
|
||||
}
|
||||
}
|
||||
Load_Vsphere([VirtualizerAssistant] $assistant) {
|
||||
$vsphere_urls = $this._Get_Hosts_From_File($this._VSPHERE_FILE)
|
||||
foreach ($url in $vsphere_urls) {
|
||||
$assistant.append_session([vSphereServer], $url)
|
||||
}
|
||||
}
|
||||
|
||||
[String[]]_Get_Hosts_From_File($filepath)
|
||||
{
|
||||
if (-not(Test-Path -Path $filepath -PathType Leaf)) {
|
||||
[String]::Format("File {0} doesn't exist, skipping ...",$filepath) | Write-Host
|
||||
return @()
|
||||
}
|
||||
## In a future use a yaml as a .conf *or a json* (with the hyperv and vmware listed)
|
||||
$file_content = Get-Content "$filepath"
|
||||
$splitted_file_content = $file_content.Split()
|
||||
$host_array=@()
|
||||
foreach ($hostname in $splitted_file_content)
|
||||
{
|
||||
if ($hostname)
|
||||
{
|
||||
$host_array+=$hostname
|
||||
}
|
||||
}
|
||||
return $host_array
|
||||
}
|
||||
[String[]]Get_Hosts_To_Find(){
|
||||
return $this._Get_Hosts_From_File($this._HOSTS_FILE)
|
||||
}
|
||||
|
||||
|
||||
Load_All_Servers([VirtualizerAssistant] $assistant){
|
||||
$this.Load_Hyperv($assistant)
|
||||
$this.Load_Scvmm($assistant)
|
||||
$this.Load_Vsphere($assistant)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Menu{
|
||||
|
||||
$exit=$false
|
||||
[VirtualizerAssistant]$Assistant
|
||||
[Config]$Config
|
||||
|
||||
_print_menu(){
|
||||
Write-Host "Select an option an option:"
|
||||
Write-Host @"
|
||||
`t- 0 Attempt to log in into the servers (authenticates with the current session)
|
||||
`t- 1 Load VMs
|
||||
`t- 2 Find Hosts
|
||||
# `t- 3 Disconnect from all servers and reload server list content (??)
|
||||
# `t- 4 Reload VM file list content (??)
|
||||
`t- -1 Exit
|
||||
"@
|
||||
}
|
||||
Log_In(){
|
||||
$this.Config.Load_All_Servers($this.Assistant)
|
||||
}
|
||||
Load_VM(){
|
||||
$this.Assistant.load_hosts()
|
||||
}
|
||||
Find_Hosts(){
|
||||
$this.Assistant.find_hosts($this.Config.Get_Hosts_To_Find())
|
||||
}
|
||||
|
||||
|
||||
_select_menu(){
|
||||
$uinput=Read-Host "Please enter your option"
|
||||
switch ($uinput) {
|
||||
-1 {
|
||||
$this.Quit()
|
||||
}
|
||||
0 {
|
||||
$this.Log_In()
|
||||
}
|
||||
1 {
|
||||
$this.Load_VM()
|
||||
}
|
||||
2 {
|
||||
$this.Find_Hosts()
|
||||
}
|
||||
# 3 {
|
||||
# $this.Disconnect()
|
||||
# }
|
||||
Default {
|
||||
Write-Host "Error, try again"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu(){
|
||||
$this.Assistant=[VirtualizerAssistant]::new()
|
||||
$this.Config=[Config]::new()
|
||||
while (!$this.exit){
|
||||
$this._print_menu()
|
||||
$this._select_menu()
|
||||
}
|
||||
}
|
||||
Quit(){
|
||||
Write-Host " -> Bye!"
|
||||
$this.exit=$true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Advanced params?
|
||||
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7.2
|
||||
function load_hyperv($manager) {
|
||||
$hyperv_urls = Get-Hosts-From-File($HYPERV_FILE)
|
||||
foreach ($url in $hyperv_urls) {
|
||||
$manager.append_session([HypervisorServer], $url)
|
||||
}
|
||||
}
|
||||
|
||||
function load_scvmm($manager) {
|
||||
$hyperv_urls = Get-Hosts-From-File($SCVMM_FILE)
|
||||
foreach ($url in $hyperv_urls) {
|
||||
$manager.append_session([SystemCenterVirtualMachineManager], $url)
|
||||
}
|
||||
}
|
||||
#
|
||||
#function Test_VM{
|
||||
# $_____url=$_____url
|
||||
# $manager = [VirtualizerAssistant]::new()
|
||||
# $manager.append_session([SystemCenterVirtualMachineManager], $_____url)
|
||||
# $manager.__connected_servers[0].get_host_list()[0]
|
||||
#}
|
||||
|
||||
|
||||
|
||||
function Main{
|
||||
$manager = [VirtualizerMiddleware]::new()
|
||||
load_scvmm($manager)
|
||||
$manager.load_hosts()
|
||||
$vmhosts = Get-Hosts-From-File($HOSTS_FILE)
|
||||
$manager.find_hosts($vmhosts)
|
||||
}
|
||||
function Test_VM{
|
||||
$_____url=$_____url
|
||||
$manager = [VirtualizerMiddleware]::new()
|
||||
$manager.append_session([SystemCenterVirtualMachineManager], $_____url)
|
||||
$manager.__connected_servers[0].get_host_list()[0]
|
||||
$menu = [Menu]::new()
|
||||
# load_vsphere($manager)
|
||||
# $manager.load_hosts()
|
||||
# $vmhosts = Get-Hosts-From-File($HOSTS_FILE)
|
||||
# $manager.find_hosts($vmhosts)
|
||||
# $manager.__found_host_dict
|
||||
}
|
||||
|
||||
Main
|
||||
@ -279,7 +500,12 @@ Main
|
||||
# get_status
|
||||
# list_snaps
|
||||
# Replace virtual host terminology with virtual machine
|
||||
|
||||
|
||||
|
||||
# add to middleware, load hyperv_from_file($path)
|
||||
# mayb load all the snapshots into the object, but unsure how it would affect the performance, afterwards can filter by name
|
||||
# Check login into svcmm specifying the server (this will allow async)
|
||||
# Check login vmware
|
||||
# Check get VM from vcenter
|
||||
# Mayb some background/Async process.
|
||||
# Mayb a function/Class to load the arguments and create some conf
|
||||
# Sort Snaps by date (newest to oldes)
|
||||
|
||||
|
@ -32,7 +32,7 @@ At C:\Users\Mamoncete\Desktop\test.ps1:50 char:8
|
||||
|
||||
======================================
|
||||
```sh
|
||||
Get-SCVMMServer -ComputerName "VMMServer01.Contoso.com" -TCPPort 8100
|
||||
Get-SCVMMServer -ComputerName "VMMServer01.Cosco.com" -TCPPort 8100
|
||||
```
|
||||
https://docs.microsoft.com/en-us/powershell/module/virtualmachinemanager/get-scvmmserver?view=systemcenter-ps-2022
|
||||
|
||||
@ -56,4 +56,32 @@ Get-Command -Module hyper-v | Out-GridView
|
||||
|
||||
##### Niputis
|
||||
|
||||
https://livebook.manning.com/book/windows-powershell-in-action-third-edition/chapter-2/40
|
||||
https://livebook.manning.com/book/windows-powershell-in-action-third-edition/chapter-2/40
|
||||
```powershell
|
||||
Connect-VIServer -Server 10.23.112.235 -Protocol https -User admin -Password pass
|
||||
```
|
||||
|
||||
https://thesysadminchannel.com/get-all-vmware-snapshots-using-powercli-module/
|
||||
```powershell
|
||||
Get-VM | Get-Snapshot | select VM, Name, Created
|
||||
```
|
||||
|
||||
```powershell
|
||||
format-list
|
||||
```
|
||||
|
||||
|
||||
# Async/background
|
||||
|
||||
https://adamtheautomator.com/powershell-async/
|
||||
|
||||
Mayb do a list of background processes, when it finishes/breaks or something removes itself?
|
||||
Mayb a list of pids, a loop that checks if the pid still running, if it is running it waits, if it isnt it get removed, resumes when all ended?
|
||||
|
||||
|
||||
## "Best practices"
|
||||
https://adamtheautomator.com/powershell-best-practices/
|
||||
|
||||
# Sort-Object
|
||||
|
||||
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/sort-object?view=powershell-7.2
|
Loading…
x
Reference in New Issue
Block a user