Powershell Diagram vCenter

This is a script that I got from someone else but have modified pretty heavily. This will use Powershell to diagram vCenter. This will connect to vCenter, pull a list of clusters and for each cluster it will create a Visio diagram and detail host, datastore and VM info. For this to run you need to have Visio installed. You also need these templates which apparently I’m not allowed to link to but you can find them pretty easy. The two non-standard ones I use are “EUC Visio Stencils 2018” and “Security and Systems Stencil.” You don’t NEED to use mine just make sure you update the section of the script that ties a stencil to a type of system. (its commented in there starting at line 69). The last thing needed is the PowerCLI module installed. You can see how that works here.

Script:

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$creds = get-credential -Message "Enter your vCenter Creds"}

$vCenter_Server = "vCenter_Server_Name"
Connect-VIServer -server $vCenter_Server -Credential $creds -force
$allclusters = Get-Cluster

foreach ($cluster in $allclusters)
{
$shpFile1 = "EUC Visio Stencils 2018.vss"
$shpFile2 = "Security and Systems Stencil.vssx"
$shpFile3 = "Basic Shapes.vss"
 
#VISIO Function for the Connection-of-objects  
function connect-visioobject ($firstObj, $secondObj)  
{  
    $shpConn = $pagObj.Drop($pagObj.Application.ConnectorToolDataObject, 0, 0)  
    #// Connect its Begin to the 'From' shape:  
    $connectBegin = $shpConn.CellsU("BeginX").GlueTo($firstObj.CellsU("PinX"))  
    #// Connect its End to the 'To' shape:  
    $connectEnd = $shpConn.CellsU("EndX").GlueTo($secondObj.CellsU("PinX"))  
}  
 
#VISIO Function for adding the object into the drawing  
function add-visioobject ($mastObj, $item)  
{  
         Write-Host "Adding $item"  
        # Drop the selected stencil on the active page, with the coordinates x, y  
          $shpObj = $pagObj.Drop($mastObj, $x, $y)  
        # Enter text for the object  
          $shpObj.Text = $item
         
        #Resize the object
          $shpObj.Resize(1,150,33)
          
        
        #Return the visioobject to be used  
        return $shpObj  
 }  
 
# Create VI Properties to extract vmtype
 
New-VIProperty -Name GuestFamily -ObjectType VirtualMachine -ValueFromExtensionProperty 'guest.guestfamily' -Force | Out-Null
New-VIProperty -Name GuestOSType -ObjectType VirtualMachine -ValueFromExtensionProperty 'guest.guestfullname' -Force | Out-Null
 
 
# Create an instance of Visio and create a document based on the Basic Diagram template.  
$AppVisio = New-Object -ComObject Visio.Application -ErrorAction Stop
$AppVisio.Visible = $false
$docsObj = $AppVisio.Documents  
$DocObj = $docsObj.Add("Basic Network Diagram.vst")  
 
# Set the active page of the document to page 1  
$pagsObj = $AppVisio.ActiveDocument.Pages  
$pagObj = $pagsObj.Item(1)  
 
# Load a set of stencils and select one to drop  
$stnPath = [system.Environment]::GetFolderPath('MyDocuments') + "\My Shapes\"  
$stnObj1 = $AppVisio.Documents.Add($stnPath + $shpFile1)  
$stnObj2 = $AppVisio.Documents.Add($stnPath + $shpFile2)
$stnObj3 = $AppVisio.Documents.Add($shpFile3)

$VirtualMachine = $stnobj1.Masters.item("Virtual Machine (3D)") 
$Windows = $stnobj1.Masters.item("Microsoft")
$PoweredOff =  $stnobj2.Masters.item("VM State Saved")
$Linux =  $stnobj2.Masters.item("Linux")
$VirtualAppliance = $stnobj1.Masters.item("3D Virtual Appliance")  
$vSphere = $stnobj1.Masters.item("vCenter")
$Clusters = $stnobj1.Masters.item("Cluster")
$VMware_Host=$stnobj1.Masters.item("ESXi Host")
$datastores=$stnobj1.Masters.item("Storage 1")
$vSwitchObject=$stnobj1.Masters.item("vSwtch 3D")
$Network = $stnobj2.Masters.item("Process")
$Switch = $stnobj1.Masters.item("Switch")
$Firewall = $stnobj1.Masters.item("Router 1")
$Rectangle = $stnObj3.Masters.item("Rounded Rectangle")


 
$allNODES = Get-Cluster $cluster | get-vmhost
$allclusters = Get-Cluster $cluster
$allVMs = Get-Cluster $cluster | Get-VM  
$allDs = Get-Cluster $cluster | Get-Datastore

 
 
#Set Start Locations of Objects  
$x = 1  
$y = .5  
 
#DRAW ALL Cluster-NODES  
Foreach ($cluster in $allclusters) {  
    $y += 0.25  
    $VMs_Total = get-cluster $cluster | get-vm | Measure-Object | Select-Object -ExpandProperty count
    $clusterInfo = "Cluster: " + $cluster.Name + "`nTotal VMs: " + $VMs_Total
    $clusterObj = add-visioobject $Clusters $clusterInfo
  
#Find Datastores and draw them
    Foreach ($d in $allDs) {  
          
            #calculate percent free            
            $percentFree = [math]::Round(($d.FreeSpaceGB / $d.CapacityGB * 100),0)
            $x = -3             
            $dsInfo = "Datastore: " + $d.Name  + "`nCapacity: " + [math]::Round([decimal]$d.CapacityGB,2) + "GB`nFree Space: " + [math]::Round([decimal]$percentFree,2) + "%"
            $datastoreObj = add-visioobject $datastores $dsInfo  
            connect-visioobject $clusterObj $datastoreObj
            $y += 4     
    }

    $allvSwitches = Get-VMHost $allNODES[0] | Get-VirtualSwitch
        $x +=4
    #DRAW ALL Virtual Switches and connect them to the cluster object
        Foreach ($vSwitch in $allvSwitches) {  
                
            $Portgroups = Get-VirtualPortGroup -VirtualSwitch $vSwitch | Select-Object name, vlanid
            $portgroupnames = ""
            foreach ($pg in $Portgroups){
                $name = $pg.name
                $vlan = $pg.vlanid
                $portgroupnames = $portgroupnames + "$name($vlan)`n" 
            
            }
            $x += 5  
            $y = -1
            #$vmCount = Get-VMHost $allNODES[0] | Get-VirtualPortGroup | get-vm | Measure-Object | Select-Object -ExpandProperty count  
            $vsInfo = "vSwitch: " + $vSwitch.Name  + "`nPortgroupname(Vlan): " + $portgroupnames #+ "`nVM Count: " + $vmCount
            $vSwitches = add-visioobject $vSwitchObject $vsInfo  
            connect-visioobject $ClusterObj $vSwitches

        }
    
            $y +=15
#DRAW ALL Physical VMHOST NODES with Node Name, Total Memory and vCenter version and connect them to the cluster object
    Foreach ($node in $allNODES) {  
          
            $x = 5  
            
            $Mem_Percent = [math]::Round(($node.MemoryUsageGB / $node.MemoryTotalGB * 100),0)
            $VMs_Total = Get-vmHost $node | get-vm | Measure-Object | Select-Object -ExpandProperty count  
            $nodeInfo = "Host: " + $node.Name  + "`neSXIVersion: " + $node.Version + "`nTotalMemory: " + [math]::Round([decimal]$node.MemoryTotalGB,2) + "GB`nUsed Memory: " + [math]::Round([decimal]$Mem_Percent,2) + "%" + "`nTotal VMs: " + $VMs_Total
            $nodeObj = add-visioobject $VMware_Host $nodeInfo  
            connect-visioobject $clusterObj $nodeObj      
            


# GET All Virtual Machines and drwa them based on the OS type and connect them to the Node object.
$allVMNodes = Get-VMHost $node | Get-VM | select guestfamily,name,NumCpu,MemoryGB,guestostype,notes,PowerState 
                $y -= 1.5
        foreach ($vm in $allVMNodes) {   
        
            $x += 5          
            #$y += 1.5
            $guestinfo = Get-VMGuest $vm.name | Select-Object IPAddress,Disks, Nics
            $ipinfo = ""
            foreach($nic in $guestinfo.Nics){
                $ipinfo += $nic.device.networkname + " - " + $nic.IPAddress + "`n"

            }

            $diskinfo = ""
            foreach($disk in $guestinfo.Disks){
                $diskinfo += $disk.Path + "`nCapacity: " + [math]::Round($disk.CapacityGB,2)  + "GB`nFree Space: " + [math]::Round($disk.FreeSpaceGB,2) + "GB`n"
            }
            $vmInfo = "VM Name: " + $vm.Name + "`n`nVM OS: " + $vm.guestostype + "`n`nCPU count: " + $vm.NumCPU + "`nRAM: " + $vm.MemoryGB + "GB`n`nIP: " + $ipinfo + "`nDisk Info: `n" + $diskinfo + "`n`nNotes: " + $vm.notes  
            if ($vm.GuestOSType -like "*Windows*") {
                $VirtualMachineObj = add-visioobject $Windows $vmInfo
            }
            elseif ($vm.GuestOSType -like "*Linux*") {
                $VirtualMachineObj = add-visioobject $Linux $vmInfo
            }
            elseif ($vm.GuestOSType -like "*CentOS*") {
                $VirtualMachineObj = add-visioobject $Linux $vmInfo
            }
            elseif ($vm.PowerState -eq "PoweredOff") {
                $VirtualMachineObj = add-visioobject $PoweredOff $vmInfo
            } 
            else {
                $VirtualMachineObj = add-visioobject $VirtualMachine $vmInfo
            }
           
            connect-visioobject $nodeObj $VirtualMachineObj  
        
        }  
        $y += 15
        }
 
        }
        
        $y -= 12
        $x = -2
     



# Resize the Visio so that all fits in one page, nice and clean.
$pagObj.AutoSizeDrawing()
$pagObj.ResizeToFitContents()  

# Save the Visio file generated in desktop for each of the cluster.
$DocObj.SaveAs("C:\$cluster-Detailed.vsd")
$pagObj.Export("C:\$cluster-Detailed.png")
$AppVisio.quit()
Write-Host "Finished $cluster"
        
}
#Stop-Process -Name "*Visio*"
Write-Host "Complete!"
Tagged : / /

Powershell Install SCCM Client

There have been times where I have run into issues where the SCCM client doesn’t install on a new server or I am trying to finish a server setup quickly and I don’t want to wait for SCCM to do it automatically. Here is a little snip that will let you put a list of server or workstions into an array and it will copy the client locally and then run user powershell to install SCCM client.

Script:

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$creds = get-credential -Message "Enter your Domain Admin Creds"}

#Change this path, this should be pretty close to yours
$ClientPath = "\\SCCM_Server_Name\SMS_SITE\Client\ccmsetup.exe"

#List of Servers goes here
$servers = (
    "Server1",
    "Server2",
    "Server3" 
)

#This will clear any PSSessions
Remove-PSSession *

#Creates a PSSession for each server defined above and copies the most current client .exe locally
foreach ($server in $servers) {
    $s = New-PSSession -ComputerName $server -Credential $Creds
    Copy-Item $ClientPath -Destination "C:\ccmsetup.exe" -ToSession $s -Force
    Remove-PSSession $s
}

#Runs the client installer
$s = New-PSSession -ComputerName $servers -Credential $Creds
Invoke-Command -Session $s -ScriptBlock {
    cd C:\ ;
    .\ccmsetup.exe /mp:SCCM_Server_Name /logon SMSSITECODE=AUTO FSP=SCCM_Server_Name;
}
Tagged : / /

Powershell Connection Examples

In this post I’m going to show you a few different ways to connect to thing using Powershell. I will make other posts that go into more detail and explain each one but this is more of a reference post. I will probably update this post in the future to include more but this current list includes Powershell Connection Examples for: Active Directory (on-prem), AzureAD, Exchange (on-prem), Exchange Online, vCenter and SCCM. Like all my posts I’m not claiming these are the only ways but these are the ways I use and they work. For these you may need to set you execution policy for these to work:

Set-ExecutionPolicy -ExecutionPolicy Bypass
Active Directory (On-Prem)
#set Variable for which Domain Controller to connect to
$Domain_Controller = "MyDC1"

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$Creds = get-credential -Message "Enter your Domain Admin Creds"}

#Connect to Domain Controller and import a Active Directory Session
$session = New-PSSession -ComputerName $Domain_Controller -Credential $creds
Invoke-Command $session -Scriptblock { Import-Module ActiveDirectory }
Import-PSSession -Session $session -module ActiveDirectory

Test Command

Get-ADuser username
Example of Active Directory Connection with Powershell
Example of Active Directory Connection with Powershell
AzureAD (MSOL)

For this you need to have the the MSOnline module installed you can get it by running:

Install-Module MSOnline -verbose

There are two ways to run this and it depends on if you have MFA setup and Trusted locations:
Option 1 –
If you do NOT have MFA setup OR you have MFA setup but you are logging in from a “Trusted Location”

#Check for Creds and ask for them if they aren't found
if (!($365Creds)) {$365Creds = get-credential -Message "Enter your Office365 Admin Creds"}

#Make the connection
Connect-MsolService -Credential $365Creds

Option 2 – If you have MFA on and aren’t at a “Trusted Location”

Connect-MsolService


Test Connection

Get-MsolUser -UserPrincipalName [email protected]
Example of Azure AD Connection with Powershell
Example of Azure AD Connection with Powershell
Exchange (On-Prem)
#Set Exchange Server Name
$Exc_Server = "ExchangeServerName"

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$Creds = get-credential -Message "Enter your Domain Admin Creds"}

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$Exc_Server/PowerShell/ -Authentication Kerberos -Credential $creds

Import-PSSession $Session

Test Command

Get-Mailbox username
Example of Exchange Connection with Powershell
Example of Exchange Connection with Powershell
Exchange Online

For this you need the ExchangeOnlineManagement module installed. To install it run:

Install-Module ExchangeOnlineManagement

To connect use this:

Connect-ExchangeOnline

Test Command:

Get-Mailbox [email protected]
Example of Exchange Online Connection with Powershell
Example of Exchange Online Connection with Powershell
vCenter

For this you need the VMwarePowercli module installed. to install run:

Install-Module VMware.PowerCLI -AllowClobber

To connect:

If you do not have an SSL certificate on your vCenter you will need to set it to ignore your self signed cert with

Set-PowerCLIConfiguration -InvalidCertificateAction ignore

Next set your vCenter server with this command. Change vCenterServerName to match your vCenter server

#Set vCenter Servername
$vCenter_Server = "vCenterServerName"

Here is the actual connection commands, not need to change anything here. It will bring up a credential box. Enter your vCenter creds in domain\username format.

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$Creds = get-credential -Message "Enter your vCenter Admin Creds in domain\username format"}

Connect-VIServer -server $vCenter_Server -Credential $creds

Test Command:

get-Cluster
Example of vCenter Connection with Powershell
Example of vCenter Connection with Powershell
SCCM

The last Powershell Connection Example I have for you is SCCM. For this one you need to have the SCCM console installed locally or run this from the SCCM server. The console is specific to the version of SCCM you are running, you can get the console install from here \\SCCMSERVERNAME\SCCMConsoleInstaller\consoleinstaller.exe

To connect:

There are a few things to change in the below. Change SITENAME to your SCCM site name in both places, and change SCCM_Server_Name with your SCCM server name.

#Check for Creds and ask for them if they aren't found
if (!($Creds)) {$Creds = get-credential -Message "Enter your Domain Admin Creds"}

Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
New-PSDrive -Credential $Creds -Name "SITENAME" -PSProvider "AdminUI.PS.Provider\CMSite" -Root "SCCM_Server_name" -Description "Primary site"
Set-Location SITENAME:

Test command:

Get-CMSite
Example of SCCM Connection with Powershell
Example of SCCM Connection with Powershell
Azure

Connecting to Azure is similar to AzureAD or Exchange online. First, you need the module. Once it is installed, you can now connect. One important thing to note is this AZ module is newer. If you have used the Azure or AzureRM modules in the past you need to remove them with uninstall-module.

Uninstall AzureRM:

Uninstall-AzureRm

Install Module:

 Install-Module az -AllowClobber

Once the module is install you can now connect.

Connect to Azure:

Connect-AzAccount

This will open another window where you can sign into Azure using your credentials.

Test Command:

Get-AzSubscription
Azure Connection Example
Tagged : / / / /