VMWARE ESXi - Untick "Override" programmatically - vmware

This is one of the Networks attached to vSwitch0.
I'd like to untick "Override" as I'd like for it to inherit from the main settings. The thing is I have a few dozens of those and I want to do it via a script. I was not able to find how to do it via ESXCLI. The override occures when you create characteristics for the portgroup, see the following 2 commented out.
esxcli network vswitch standard portgroup add --portgroup-name=Grid --vswitch-name=vSwitch0
esxcli network vswitch standard portgroup set --portgroup-name=Grid --vlan-id 123
#esxcli network vswitch standard portgroup policy failover set --portgroup-name=Grid --active-uplinks=vmnic0,vmnic2
#esxcli network vswitch standard portgroup policy failover set --portgroup-name=Grid -l portid
I really dont want to re-create everything. There must be a way to untick those boxes.

you can do that with powercli:
$vs = Get-VirtualSwitch -VMHost $vmhost -Name "vSwitch0"
$nics = (Get-VirtualSwitch -VMHost $vmhost).Nic
$policy1 = Get-VirtualPortgroup -VirtualSwitch $vs -VMHost $vmhost -Name 'net2' | Get-NicTeamingPolicy
$policy1 | Set-NicTeamingPolicy -MakeNicActive $nics[0] -MakeNicStandby $nics[1] # this will set the order
$policy1 | Set-NicTeamingPolicy -InheritFailoverOrder $true # this will uncheck/check the failover inherit tick
if doing with esxcli:
first we get current settings (override is not checked)
[root#esx:~] esxcli network vswitch standard portgroup policy failover get -p net2
Load Balancing: srcport
Network Failure Detection: link
Notify Switches: true
Failback: true
Active Adapters: vmnic5, vmnic4
Standby Adapters:
Unused Adapters:
Override Vswitch Load Balancing: false
Override Vswitch Network Failure Detection: false
Override Vswitch Notify Switches: false
Override Vswitch Failback: false
Override Vswitch Uplinks: false
next we run the command to set the nicorder we would like to have and check again.
[root#esx:~] esxcli network vswitch standard portgroup policy failover set -a vmnic5 -s vmnic4 -p net2
[root#esx:~] esxcli network vswitch standard portgroup policy failover get -p net2
Load Balancing: srcport
Network Failure Detection: link
Notify Switches: true
Failback: true
Active Adapters: vmnic5
Standby Adapters: vmnic4
Unused Adapters:
Override Vswitch Load Balancing: false
Override Vswitch Network Failure Detection: false
Override Vswitch Notify Switches: false
Override Vswitch Failback: false
Override Vswitch Uplinks: true
this will tick the override checkbox and set the active nic to vmnic5 and stby to vmnic4
Good luck
Pargit

I rigged up a script with PowerCLI.
Cant believe I didnt think of using it...
$vmhost = 'server_name'
$portgroups = Get-VirtualPortGroup -VirtualSwitch vSwitch0 -VMHost $vmhost | select -ExpandProperty Name | sort
foreach ( $portgroup in $portgroups ) {
$portgroup
Write-Output ""
$policy1 = Get-VirtualPortGroup -VirtualSwitch vSwitch0 -VMHost $vmhost -Name $portgroup | Get-NicTeamingPolicy
Write-Output "Load Balancing: "
$policy1.IsLoadBalancingInherited
if (!($policy1.IsLoadBalancingInherited)) { $policy1 | Set-NicTeamingPolicy -InheritLoadBalancingPolicy $true }
Write-Output "Network Failure Detection: "
$policy1.IsNetworkFailoverDetectionInherited
if (!($policy1.IsNetworkFailoverDetectionInherited)) { $policy1 | Set-NicTeamingPolicy -InheritNetworkFailoverDetectionPolicy $true }
Write-Output "Notify Switches: "
$policy1.IsNotifySwitchesInherited
if (!($policy1.IsNotifySwitchesInherited)) { $policy1 | Set-NicTeamingPolicy -InheritNotifySwitches $true }
Write-Output "Failback: "
$policy1.IsFailbackInherited
if (!($policy1.IsFailbackInherited)) { $policy1 | Set-NicTeamingPolicy -InheritFailback $true }
Write-Output "Failover Order: "
$policy1.IsFailoverOrderInherited
if (!($policy1.IsFailoverOrderInherited)) { $policy1 | Set-NicTeamingPolicy -InheritFailoverOrder $true }
Write-Output ""
Write-Output ""
}

Related

powercli site recovery manager: determine which protection group an unprotected VM will be in. SRM uses array based replication

I use automation to deply VM's to various vcenter clusters.
I then confgiure SRM network mapping to create a network map between the cluster that the VM is in and the cluster which is used for DR purposes, in the protection group for those two clusters.
SRM is set up for array based replication, so as long as the VM is placed on replicated storage in the right cluster it will appear in SRM under the protection group, if a network mapping is in place then the VM will be auto protected by SRM or via my SRM config script.
I currently have the primary cluster, DR cluster and protection group hard coded, but would like to determine the protection group a VM is in and the name of the two clusters which the protection group is set up for, that way any changes to cluster configuration is automatically picked up and doesn't require manual changes to the SRM config script.
I've looked in the SRM API docs but it's not something I have worked out yet!
I have solved the issue:
$credential = Get-Credential
$server_name = "test-server"
Connect-VIServer -Server $primaryDC -Credential $credential
$srmConnection = Connect-SrmServer -Credential $credential -RemoteCredential $credential
Connect-VIServer -Server $secondaryDC -Credential $credential
$srmApi = $srmConnection.ExtensionData
$protectionGroups = $srmApi.Protection.ListProtectionGroups()
foreach ($protectionGroup in $protectionGroups){
$associatedVms = $protectionGroup.ListProtectedDatastores() | Get-VIObjectByVIView | Get-VM | Where-Object {($_.name -eq $server_name) -and($_.ExtensionData.Config.ManagedBy.ExtensionKey -ne 'com.vmware.vcDr' )}
foreach ($vm in $associatedVms) {
if ($vm.Name -eq $server_name) {
$protection_group_name = $protectionGroup.GetInfo().Name
$primary_cluster = get-vm -name $server_name | get-cluster
$primary_cluster_res_group = $primary_cluster.ExtensionData.ResourcePool
$srm_resource_groups = $srmApi.inventoryMapping.getResourcePoolMappings()
foreach ($resource_group in $srm_resource_groups){
if ($resource_group.PrimaryObject -eq $primary_cluster_res_group){
$secondary_res_group = $resource_group.SecondaryObject
}
}
}
}
}
$secondary_cluster = Get-Cluster | Where-Object {$_.ExtensionData.ResourcePool -eq $secondary_res_group}
Write-Host "VM: $vm - Protection Group: $protection_group_name - Primary cluster: $primary_cluster - Secondary cluster: $secondary_cluster - Primary ResGrp: $primary_cluster_res_group - Secondary ResGrp: $secondary_res_group"

Unable to register targets on AWS Target group

I am trying to setup an automated DNS deployment using powershell. I have written a powershell script that creates TargetGroup, registers instances to the TG, creates an ALB and adds a listener to it. Once, that is done, it creates R53 RecordSet and creates an A record to the ALB DNS.
I am having issues in having the instances registered to the TargetGroup.
This is my code snippet to that section:
$searchFor1 =#( #{name = 'tag:Name'; values = $target1})
$searchFor2 =#( #{name = 'tag:Name'; values = $target2})
$id1 = (Get-EC2Instance -Filter $searchFor1).Instances | select InstanceId
$id2 = (Get-EC2Instance -Filter $searchFor2).Instances | select InstanceId
# Create Target Group
$tg = New-ELB2TargetGroup -TargetType "instance" -HealthyThresholdCount 4 -Name $custname -Port $siteport -Protocol "HTTP" -UnhealthyThresholdCount 4 -VpcId $vpcid
Start-Sleep -s 120
$addid1 = New-Object Amazon.ElasticLoadBalancingV2.Model.TargetDescription
$addid2 = New-Object Amazon.ElasticLoadBalancingV2.Model.TargetDescription
$addid1.Id = $id1.InstanceId
$addid2.Id = $id2.InstanceId
$addid1.Port = $siteport
$addid2.Port = $siteport
$tgarn = (Get-ELB2TargetGroup -Name $custname).TargetGroupArn
Register-ELB2Target -TargetGroupArn $tgarn -Target #($addid1)
Register-ELB2Target -TargetGroupArn $tgarn -Target #($addid2)
It throws below error:
Register-ELB2Target : An instance ID must be specified
At C:\scripts\Distinct-DNS-Deployment.ps1:107 char:1
+ Register-ELB2Target -TargetGroupArn $tgarn -Target #($addid1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Amazon.PowerShe...LB2TargetCmdlet:RegisterELB2TargetCmdlet) [Register
-ELB2Target], InvalidOperationException
+ FullyQualifiedErrorId : Amazon.ElasticLoadBalancingV2.AmazonElasticLoadBalancingV2Exception,Amazon.PowerShell.Cm
dlets.ELB2.RegisterELB2TargetCmdlet
I have checked a similar post here. And the corresponding posts, so far nothing helped. I am wondering if anyone can guide me what am I doing wrong?
I have tried to run each line one by one and that happens to register the instance to the TargetGroup, just the script fails.
Instances are t2.micro and they are in running state.
As per the https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/ElasticLoadBalancingV2/TTargetDescription.html -
the Amazon.ElasticLoadBalancingV2.Model.TargetDescription is about 'Information about a target' -
which means, you should be assigning a single instance id Also, if you take a close look at the properties:
AvailabilityZone System.String
Id System.String
Port System.Int32
The result of your instance search may or may not be single output - you should keep them in loop to create each target via TargetDescription
$Instances = (Get-EC2Instance -Filter #{Name="tag:auto-delete";Value="no"}).instances |select instanceid
$theVpc = get-ec2vpc -VpcId vpc-4565e5c4
$name = "new-tg"
$port = "80"
$protocol = "HTTP"
$tg = New-ELB2TargetGroup -TargetType "instance" -HealthyThresholdCount 4 -Name $name -Port $port -Protocol "HTTP" -UnhealthyThresholdCount 4 -VpcId $theVpc.VpcId
$tgarn = (Get-ELB2TargetGroup -Name $name).TargetGroupArn
If($instances -ne $null){
foreach ($instance in $instances ){
$addid1 = New-Object Amazon.ElasticLoadBalancingV2.Model.TargetDescription
$addid1.Id = $Instance.instanceid
$addid1.Port = $port
Register-ELB2Target -TargetGroupArn $tgarn -Target #($addid1)
Remove-Variable addid1
}
}
else {
echo "There were no instances with the matching filter"
}

Pull Server names and ip address and see if they're live

I am looking to run a PowerShell script that will pull all servers from AD, show me the FQDN and IP address as well as tell me if the server is pinging.
I have a couple of scripts that do certain parts but would like to get something all in one and am having a hard time doing it.
Ping a list of servers:
$ServerName = Get-Content "c:\temp\servers.txt"
foreach ($Server in $ServerName) {
if (test-Connection -ComputerName $Server -Count 2 -Quiet ) {
"$Server is Pinging "
} else {
"$Server not pinging"
}
}
I also have a script to pull all servers from AD which shows server name, FQDN, and OS version:
Import-Module ActiveDirectory
Get-ADComputer -Filter {OperatingSystem -like '*Windows Server*'} -Properties * |
select Name, DNSHostName, OperatingSystem
Any help in getting a script to show me all servers in my environment with FQDN, IP address and if there live would be appreciated.
You should only choose desired properties with the -Property argument and not pull everything through network with *. Also quotes should be used with -Filter, not braces.
You can add a calculated property to Select-Object and get the value from Test-NetConnection:
Get-ADComputer -Filter "OperatingSystem -like '*Windows Server*'" -Properties dnshostname, operatingsystem |
Select-Object name, dnshostname, operatingsystem, `
#{n="PingSucceeded";e={(Test-NetConnection $_.name).PingSucceeded}}

EC2 User data - Disable it after all conditions are met in user data

I'm trying to rename hostname and add to AD of a spot instance. It is a simple powershell script. I've read the docs that by default user data will be disable after it gets executed once and if <persist>true</persist> is used it will not be disabled.
I think I saw somewhere this(enabling to be run at each startup) is done via taskscheduler but can't find the link.
Can someone point me to the task scheduler job or the way to manually disable the userdata once my if conditions are met.
<powershell>
Set-ExecutionPolicy unrestricted -Force
$instanceName = "test-name5"
$username = "domain\username"
$password = "password" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object -typename System.Management.Automation.PSCredential($username, $password)
Start-Sleep -s 5
$hostname = hostname
$domain = (Get-WmiObject win32_computersystem).Domain
if (!($hostname -eq $instanceName)){
Rename-Computer -NewName $instanceName -restart -force
}Elseif (!($domain -eq 'my.domain.local')){
Start-Sleep -s 5
Add-Computer -DomainName my.domain.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -erroraction 'stop'
}Else {
####code to disable the running of userdata once above conditions
are met####
}
</powershell>
<persist>true</persist>
It's worth reading the ec2config-service documentation, as the setting you want is referenced in there.
You want the Ec2HandleUserData setting, which is configured in the Config.xml.
Powershell can easily update this setting:
$path = 'C:\Program Files\Amazon\Ec2ConfigService\Settings\config.xml'
$xml = [xml](Get-Content $path)
$state = $xml.Ec2ConfigurationSettings.Plugins.Plugin | where {$_.Name -eq 'Ec2HandleUserData'}
$state.State = 'Disabled'
$xml.Save($path)
I use this code when creating custom AMI's to re-enable userdata handling ($state.State = 'Enabled').
EDIT: The above is for ec2config not ec2launch which is what the OP is using. I'd missed this originally.
I this case I think you need to change the way your script runs, rather than use <persist> and then try to disable its functionality, I would remove the persist tag and call InitializeInstance.ps1 –Schedule (documentation link) in your if for the conditions you want the userdata to re-run:
if ($hostname -ne $instanceName) {
& C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
Rename-Computer -NewName $instanceName -Restart -Force
}
elseif ($domain -ne 'my.domain.local') {
& C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
Add-Computer -DomainName aws.macmillan.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -ErrorAction 'stop'
}
As I said in the comments of the previous answer, I had 3 options and since I found the aws scheduled task I went with the last option. Answering my own question since it'll be easy to spot the code.
<powershell>
Set-ExecutionPolicy unrestricted -Force
#Enter instance hostname here
$instanceName = "test-name8"
$username = "domain\username"
#Using ssm parameter store to avoid having the password in plaintext
$password = (Get-SSMParameterValue -Name AD-Password -WithDecryption $True -Region us-east-1).Parameters[0].Value | ConvertTo-SecureString -asPlainText -Force
Start-Sleep -s 3
$cred = New-Object -typename System.Management.Automation.PSCredential($username, $password)
Start-Sleep -s 5
$hostname = hostname
$domain = (Get-WmiObject win32_computersystem).Domain
if ($hostname -ne $instanceName){
Rename-Computer -NewName $instanceName -restart -force
}Elseif ($domain -ne 'my.domain.local'){
Start-Sleep -s 5
Add-Computer -DomainName my.domain.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -erroraction 'stop'
}Else {
Disable-ScheduledTask -TaskName "Amazon Ec2 Launch - Userdata Execution"
Unregister-ScheduledTask -TaskName "Amazon Ec2 Launch - Userdata Execution"
}
</powershell>
<persist>true</persist>
note: a role that has ssm policies must be attached while launching the server for this ssm parameter command to work.
I was solving similar issue and I had to change Windows Server 2016 hostname and enroll it to Elastic Server Fleet. Also I could not allow instance to be rebooted. I used this code to solve this.
NB. I understand that it is not direct way of doing this and has numerous drawbacks, but in my circumstances goal was achieved without negative impact.
<powershell>
$ComputerName = "MyPCRandomName"
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "Hostname" -value $ComputerName
elastic-agent enroll --enrollment-token 123 --url=321
</powershell>

I need to create to Redundant VMs (both on 2 different datastores) via function

I have defined all the needed variables in a separate Variable_Defination.ps1 file and have called it up here.
Is there a better way to do this?
I just want a script to create 2 redundant VMs both running on separate datastores and having Affinity rule set up for disaster recovery cases
. ./Variable_Defination.ps1
function CreateRedundantVMs {
Param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[string]$ClusterName,
[string]$ComputerName1,
[string]$ComputerName2,
[string]$sourcetemplate,
[string]$InfraResourcePoolName,
[string]$OSCustomizationspec,
[string]$description
)
$Viabledatastores = (Get-Cluster $ClusterName | Get-Datastore) |
Where {$_.Name -like '*vSSD*'} |
Sort-Object FreeSpaceGB -Descending |
Select -First 2 -ErrorAction 'Stop'
if ($Viabledatastores) {
$Viabledatastores
} else {
Write-Host "No Viable Datastores found"
break;
}
Write-Verbose "`n---------------------- Creating redundant VMs now ------------------------`n " -Verbose
New-VM -Name $ComputerName1 -ResourcePool $InfraResourcePoolName -Datastore $Viabledatastores[0] -Description $description -Template $sourcetemplate -OSCustomizationspec $OSCustomizationspec -DiskStorageFormat Thin
New-VM -Name $ComputerName2 -ResourcePool $InfraResourcePoolName -Datastore $Viabledatastores[1] -Description $description -Template $sourcetemplate -OSCustomizationspec $OSCustomizationspec -DiskStorageFormat Thin
Start-Sleep -s 3
Write-Host "`n -------------------------------------------------------------------------`n "
Write-Verbose -Message "Virtual Machine $ComputerName1 and $ComputerName2 Deployed. Powering On" -Verbose
Write-Host "`n -------------------------------------------------------------------------`n "
Start-VM -VM $ComputerName1
Start-VM -VM $ComputerName2
}
# calling function
CreateRedundantVMs $ClusterName $ComputerName1 $ComputerName2 $sourcetemplate $InfraResourcePoolName $OSCustomizationspec $description