Using VMware PowerCli Part 1

Since VMware 6.0 I have started to use VMware PowerCli module to automate task and checks that I do daily or for large task that would take a long time to do manually. I am going to go through installing PowerCli and some of the useful command and script that can be use to check VMware.

To install PowerCli there are some pre-req’s

OS Type
64-Bit
Server
  • Windows Server 2012 R2
  • Windows Server 2008 R2 Service Pack 1
Workstation
  • Windows 10
  • Windows 8.1
  • Windows 7 Service Pack 1
  • Windows PowerShell 3.0, 4.0, 5.0, or 5.1
  • .NET Framework 4.5, 4.5.x, 4.6, or 4.6.x

I would recommend installing the latest version of PowerShell which is currently 5.1

To check current version of PowerShell run $PSVersionTablePcli

To install the latest version install the latest Windows Management Framework 5.1 link to download page is below.

https://www.microsoft.com/en-us/download/details.aspx?id=54616

Step 1 is to install PowerCli

The old PowerCli was a PowerShell snap in and required downloading an exe to install, the new version is module based and can be installed directly from the PowerShell console. To install run the below command.

Install-Module VMware.PowerCliPcli1

If you need to update the module to a new release run

Update-Module VMWare.PowerCliPcli2

If a path is not specified the default location that the module files will be placed in is

C:\Program Files\WindowsPowerShell\Modules

Once the install has finished to verify that PowerCli is installed run the below commandPcli3

Step 2 is to connect to vCenter

To connect to vCenter open an elevated PowerShell console and import the VMware Module

Import-Module VMware.PowerCliPcli4

Connect-VIServer lab-VC vCenterServerPcli5

Once connected we can now start to run command against vCenter.

To get host information run

Get-VMHost

Pcli6

To find all VM’s that have snapshots over a certain date. I want to get all snapshots older than 1 day to change this just edit the $date variable.

$date = (Get-Date).AddDays(-1)
$Snapshot = get-vm | get-snapshot
$Snapshot | where {$_.Created -lt $date}Pcli7

To check datastores you can run

Get-Datastore

Pcli8

To get additional info you can do some math’s and use arrays to get % free space of the datastores. The below will get all datastores that have less than 25% free space.

Get-Datastore | select Name,@{N=”UsedSpaceGB”;E={[math]::Round(($_.CapacityGB),2)}},
@{N=”FreeSpaceGB”;E={[math]::Round(($_.FreeSpaceGB),2)}},
@{N=”%Free”;E={[math]::Round(($_.FreeSpaceGB)/($_.CapacityGB)*100,2)}} |
where %Free -lt “25”
Pcli9

Add secondary IP to Network Adapter Windows

A web developer was adding IP’s to some existing web server and once these were added we started having routing issue on the servers where the sites would not respond and the server could not talk back to the production network from the DMZ.

I checked the server and I was getting inconsistent results as I could ping a device sometimes but not others so it looked like a network issue.

I ran the below command to check what traffic was being sent and I saw that there where multiple IP’s being used as local address for traffic.

Get-NetTCPConnection -LocalAddress 192.168.0.*

I decided to check the skipasSource on the interface as this was the cause of a similar issue that happened before.

This command’s will return all IP’s the interface name and whether the IP is set to skipassource the new IP should have this set to true.

CMD:                                                                                                                                                Netsh int ipv4 show ipaddresses level=verbose

PowerShell:                                                                                                                                       Get-NetIPAddress | Select-Object IPAddress, InterfaceAlias, SkipAsSource

When I checked the new IP was set to false which meant both the orignal and new IP where being used. To set the IP to false I either need to remove the IP and set it using cmd or PowerShell  to set skip as source to true or Set to true using PowerShell.

If you don’t want to remove and re-add the address use the below command

Set-NetIPAddress -IPAddress “192.168.0.200” -InterfaceAlias “LAN” -SkipAsSource $false

IP3

second option is to remove the IP from the network settings and  re-add the IP using command line below is using CMD and PowerShell.

CMD:                                                                                                                                                Netsh int ipv4 add address “Interface Name” “IP Address” “Netmask” skipassource=True

Below is a full example:

Netsh int ipv4 add address “LAN” 192.168.0.200 255.255.255.0 skipassource=true

IP2

PowerShell:                                                                                                                                    NetIPAddress –IPAddress “IPAddress”  –InterfaceAlias “Interface Name” –SkipAsSource $True

Below is a full example:

New-NetIPAddress –IPAddress 192.168.0.200 -PrefixLength 24 -InterfaceAlias “LAN” –SkipAsSource $True

IP1

Once skip as source was set to true there was no connection issues.

Deploy Multiple VM’s using PowerCLI and VMware Template

I wanted to create a few different VM’s so I can test a VMware daily report script. This can be done using deploy VM from template using the vSphere web client but this can take a long time. I decided to write a quick PowerShell script to deploy the VM’s use PowerCLI. I first ran Get-Template to get the name of the template I wanted to use.

Template

I decided to use numerical numbering for my VM’s . So I used a while loop so that it would start at 1 and I added to the $i variable at the end of the loop so it would run until it hit 10. I used the variable $DS to get the datastores and piped that to get-random so the VM’s would be spread across both datastores. If you want to select just one datastore just remove the $DS variable and change the ($DS | Get-Random) to the datastore you want to select.

$DS = Get-Datastore -Name Local*
$i = 1
while ($i -le 10){
$i
New-VM -Name “Linux-VM$i” -Template “Linux-VM_Template” -Datastore ($DS | Get-Random) -VMHost “Esxihost to deploy to”
$i++
}
Deploy OVF template

I then used the below command to get the list of VM’s and their datastores.

Get-VM -Name Linux-VM* | Select Name,@{N=”Datastore”;E={(Get-Datastore -Id $_.DatastoreIdList)}}

Deploy2

 

Event ID 2213: Active Directory DFS Replication stopped

I have been seeing intermitent issues with DFS replication on multiple DC’s across our diffrent forest. This has lead to issue with group policy replication below is a copy of the event log.

The DFS Replication service stopped replication on volume C:. This occurs when a DFSR JET database is not shut down cleanly and Auto Recovery is disabled. To resolve this issue, back up the files in the affected replicated folders, and then use the ResumeReplication WMI method to resume replication. 

Additional Information: 

Volume: C: 

GUID:

Recovery Steps 

1. Back up the files in all replicated folders on the volume. Failure to do so may result in data loss due to unexpected conflict resolution during the recovery of the replicated folders. 

2. To resume the replication for this volume, use the WMI method ResumeReplication of the DfsrVolumeConfig class. For example, from an elevated command prompt, type the following command: 

wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where volumeGuid=”GUID” call ResumeReplication


To fix the issue we have had to logon to each DC and run the above wmic command to re-eneable, this is time consuming and also requires some form of alerting to know that the replication has stopped. I decided to see if I could script this and came up with a script to search each domain and then run remote Get-wmiobject and call the resume command method. The script is set to automatically run using a schedualed task. Link to technet script is below.

DFS script on Technet

Scan Annoymus FTP Script

I needed to scan all my subnets for FTP’s that had annoymus FTP access enabled. Below is the script I used this requires nmap.

Nmap can be downloaded from this site: https://nmap.org/download.html

I useally add nmap as a system variable so I can call the exe without specifying path.

  1. From the desktop, right click on This PC and then click “properties”.
  2. In the System Properties window, click the “Advanced” tab.
  3. Click the “Environment Variables” button.
  4. Choose path from the system variables section, then hit edit.
  5. Add a semi-colon and then your Nmap directory (e.g. C:\Program Files (x86)\Nmap) to the end of the value.

You can add or remove subnets ranges by changing the subnets variable (which is marked as red in the script below). The range can be specified by setting the range variable this can be set from 1 to 254 to restrict the scan. Below are two examples:

Example for a Single range
.\FTPCheck.ps1 -exportpath c:\temp -Range 20 -subnets 192.168.0.
Example for Multiple ranges
.\FTPCheck.ps1 -exportpath c:\temp -Range 254 -subnets 192.168.0.,10.10.10.
<#
.SYNOPSIS
Scan for Open FTP sites on subnets
.DESCRIPTION
The script will run through each address on the specified subnets
and scan for any open FTP sites and output any sites to a csv files
.PARAMETER exportpath
The export parameter is used to specify the export path location.
.PARAMETER Range
This parameter is used to set the scan range this can be set from 1 to 254 depending of
how much of the subnet range needs to be scanned.
.PARAMETER Subnets
This parameter is used to specify the subnets to be scanned.
.EXAMPLE
.\FTPCheck.ps1 -exportpath c:\temp -Range 20 -subnets 192.168.0.
.\FTPCheck.ps1 -exportpath c:\temp -Range 20 -subnets 192.168.0.,10.10.10.
Scan-FTP -exportpath c:\temp\export -Range 254
.NOTES
This script requires nmap to check for Open FTP sites
#>
param (
[parameter(Mandatory = $true)]
[String]$exportpath,
[parameter(Mandatory = $true)]
[String]$Range,
[parameter(Mandatory = $true)]
[string[]]$subnets
)
if(Test-Path $exportpath){
foreach($subnet in $subnets){
$i = 1
while($i -le $Range){
$results = $subnet + $i
foreach ($result in $results)
{
$report = @()
Write-Host “Checking IP” $result -ForegroundColor DarkGreen
$Scan = nmap -p 21 -v –open –script ftp-anon $result -A
$report1 = $Scan | Select-String -Pattern “Nmap scan report for “
$report2 = $Scan | Select-String -Pattern “21/tcp open ftp”
$report3 = $Scan | Select-String -Pattern “(FTP code 230)”
$report4 = $Scan | Select-String -Pattern “MAC Address:”
$Properties = @{
“FTP Site” = $report1
“FTP Site Responses” = $report2
“FTP Site Access” = $report3
“FTP MAC” = $report4
}
$report += New-Object psobject -Property $properties
if ($report1 -ne $null){
$report | select “FTP Site”,”FTP Site Responses”,”FTP Site Access”,”FTP MAC” | Export-Csv “$exportpath\FTPScan.csv” -Append -NoClobber -NoTypeInformation
Write-Warning “FTP site responded”
}
$i++
}
}
}
}
else{
Write-Warning “Path does not exist”
exit
}