PowerRestCLI.psm1

Write-Verbose 'Importing from [C:\projects\powerrestcli\PowerRestCLI\private]'
# .\PowerRestCLI\private\Invoke-ConnectionVariableSet.ps1
function Invoke-ConnectionVariableSet
{
    <#
    .DESCRIPTION
        Simple function to store variables..
    .EXAMPLE
        Invoke-ConnectionVariables
    .NOTES
        No notes.
    #>

    # Edit the vCenter IP to your server's IP or DNS name.
    [string]$script:vCenter = "192.168.2.220"
    [object]$script:headers = @()
    [object]$script:session = @()
    return $true

}
# .\PowerRestCLI\private\New-rVIHeader.ps1
function New-rVIHeader
{
    <#
    .DESCRIPTION
        Gather Credentials to to add to Connection headers.
    .EXAMPLE
        New-rViHeaders
    .EXAMPLE
        New-rViHeader -Credential $Credentials
    .EXAMPLE
        $script:header = New-rViHeaders
    .PARAMETER Credential
        A valid Credential set is required.
    .NOTES
        No notes at this time.
    #>

    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "Low"
    )]
    [OutputType([Hashtable])]
    [OutputType([boolean])]
    param(
        [Parameter(Mandatory = $true)]
        [System.Management.Automation.PSCredential]$Credential
    )
    begin
    {
        # No pre-task
    }
    process
    {
        if ($pscmdlet.ShouldProcess("Creating Headers."))
        {
            $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password))
            $script:headers = @{
                'Authorization' = "Basic $auth"
            }
            return $script:headers
        }
        else
        {
            # -WhatIf was used.
            return $false
        }
    }
}
# .\PowerRestCLI\private\New-rVIsession.ps1
function New-rVIsession
{
    <#
    .DESCRIPTION
        Perform Rest API call to retrieve new Session token.
    .PARAMETER vCenter
        A valid vCenter IP/Name is required
    .PARAMETER Headers
        Valid Headers need to passed in.
    .EXAMPLE
        $script:session = New-rVisession -headers $headers -vCenter $vCenter
    .NOTES
        No Notes.
    #>

    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "Low"
    )]
    [OutputType([Hashtable])]
    [OutputType([boolean])]
    param(
        [Parameter(Mandatory = $false)]
        [system.object]$headers,
        [Parameter(Mandatory = $true)]
        [string]$vCenter
    )
    begin
    {
        # No Pre-Task.
    }
    process
    {
        if ($pscmdlet.ShouldProcess("Creating Session."))
        {
            # Perform Rest call to create session.
            $ReturnData = Invoke-RestMethod -Uri https://$vCenter/rest/com/vmware/cis/session -Method Post -Headers $headers -UseBasicParsing
            $token = ($ReturnData).value
            if ($null -ne $token)
            {
                $script:session = @{'vmware-api-session-id' = $token}
                return $script:session
            }
            else
            {
                # No token returned.
                Throw "New-rVIsession: No token returned."
            }
        }
        else
        {
            # -WhatIf was used.
            return $false
        }
    }
}
Write-Verbose 'Importing from [C:\projects\powerrestcli\PowerRestCLI\public]'
# .\PowerRestCLI\public\Connect-rVIServer.ps1
function Connect-rVIServer
{
    <#
    .DESCRIPTION
        Retrieve a Session token from vSphere API server.
    .PARAMETER vCenter
        A valid vCenter IP/Name is required as a variable called $vCenter
    .PARAMETER User
        A valid vCenter User is required
    .PARAMETER Password
        A valid vCenter Password is required
    .PARAMETER Credential
        A valid Credential set is required
    .EXAMPLE
        Connect-rVIServer -vCenter $vCenter -Credential $Credentials
    .EXAMPLE
        Connect-rVIServer -vCenter $vCenter -user "administrator@corp.local" -password (ConvertTo-SecureString "VMware1!" -AsPlainText -force)
    .EXAMPLE
        Connect-rVIServer -vCenter $vCenter -user "administrator@corp.local" -password (read-host -AsSecureString)
    .EXAMPLE
        Connect-rVIServer -vCenter $vCenter
    .NOTES
        Returns a Session to the powershell console, If the variable is global it does not need
        to be catpured in a variable.
    #>

    [CmdletBinding()]
    [OutputType([boolean])]
    param(
        [Parameter(Mandatory = $true, ParameterSetName = 'Credential')]
        [Parameter(Mandatory = $true, ParameterSetName = 'PlainText')]
        [Parameter(Mandatory = $true, ParameterSetName = 'NoCreds')]
        [string]$vCenter,
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Credential')]
        [System.Management.Automation.PSCredential]$Credential,
        [Parameter(Mandatory = $true,
            ParameterSetName = 'PlainText')]
        [string]$User,
        [Parameter(Mandatory = $true,
            ParameterSetName = 'PlainText')]
        [System.Security.SecureString]$Password
    )
    try
    {
        # Ensure the PowerShell environment is set up to ignore self signed certs.
        if (Disable-SSLValidation)
        {
            # SSL Validation was Disabled
        }
        else
        {
            Throw "Connect-rVIServer: Unable to Disable SSL Validation."
        }
        # Determine the credential type to create appropriate header.
        if ($PSCmdlet.ParameterSetName -eq 'NoCreds')
        {
            # No Credential information was presented. Prompt user for credentials.
            $Credential = Get-Credential
        }
        elseif ($PSCmdlet.ParameterSetName -eq 'PlainText')
        {
            # User passed in Username/Password combo.
            $Credential = New-Object System.Management.Automation.PSCredential -ArgumentList ($User, $Password)
        }
        else
        {
            # User provided Credential Variable, No action needed.
        }
        # Insert the Credentials into the Header
        $script:headers = New-rVIHeader -Credential $Credential

        # Perform a Rest call and retrieve a token.
        $script:session = New-rVisession -headers $script:headers -vCenter $vCenter
        $User = $Credential.UserName
        $vCenterReturn = New-Object -TypeName PSObject
        $vCenterReturn | Add-Member -MemberType NoteProperty -Name Name -Value $vCenter
        $vCenterReturn | Add-Member -MemberType NoteProperty -Name Port -Value "443"
        $vCenterReturn | Add-Member -MemberType NoteProperty -Name User -Value $User
        # Return vCenter connection information.
        $script:vCenter = $vCenter
        $vCenterReturn
    }
    Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        Throw "Connect-rVIServer: $ErrorMessage $FailedItem"
    }
}
# .\PowerRestCLI\public\Disable-SSLValidation.ps1
function Disable-SSLValidation
{
    <#
    .SYNOPSIS
        Disables SSL certificate validation
    .DESCRIPTION
        Disable-SSLValidation disables SSL certificate validation by using reflection to implement the System.Net.ICertificatePolicy class.
        Author: Matthew Graeber (@mattifestation)
        License: BSD 3-Clause
    .NOTES
        Reflection is ideal in situations when a script executes in an environment in which you cannot call csc.ese to compile source code.
        If compiling code is an option, then implementing System.Net.ICertificatePolicy in C# and Add-Type is trivial.
    .EXAMPLE
        Disable-SSLValidation
    .LINK
        http://www.exploit-monday.com
    #>

    Set-StrictMode -Version 2
    # You have already run this function if ([System.Net.ServicePointManager]::CertificatePolicy.ToString() -eq 'IgnoreCerts') { Return }
    $Domain = [AppDomain]::CurrentDomain
    $DynAssembly = New-Object System.Reflection.AssemblyName('IgnoreCerts')
    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('IgnoreCerts', $false)
    $TypeBuilder = $ModuleBuilder.DefineType('IgnoreCerts', 'AutoLayout, AnsiClass, Class, Public, BeforeFieldInit', [System.Object], [System.Net.ICertificatePolicy])
    $TypeBuilder.DefineDefaultConstructor('PrivateScope, Public, HideBySig, SpecialName, RTSpecialName') | Out-Null
    $MethodInfo = [System.Net.ICertificatePolicy].GetMethod('CheckValidationResult')
    $MethodBuilder = $TypeBuilder.DefineMethod($MethodInfo.Name, 'PrivateScope, Public, Virtual, HideBySig, VtableLayoutMask', $MethodInfo.CallingConvention, $MethodInfo.ReturnType, ([Type[]] ($MethodInfo.GetParameters() | ForEach-Object {$_.ParameterType})))
    $ILGen = $MethodBuilder.GetILGenerator()
    $ILGen.Emit([Reflection.Emit.Opcodes]::Ldc_I4_1)
    $ILGen.Emit([Reflection.Emit.Opcodes]::Ret)
    $TypeBuilder.CreateType() | Out-Null

    # Disable SSL certificate validation
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object IgnoreCerts
    return $true
}
# .\PowerRestCLI\public\Get-rVM.ps1
function Get-rVM
{
    <#
    .SYNOPSIS
        Perform Rest API call to retrieve VM information from vCenter.
    .DESCRIPTION
        Perform Rest API call to retrieve VM information from vCenter.
    .EXAMPLE
        $vms = Get-rVM
    .NOTES
        No notes.
    #>

    begin
    {
        # Perform RestAPI call to vCenter to retrieve VM data.
        $ReturnData = Invoke-RestMethod -Uri https://$script:vCenter/rest/vcenter/vm -Method Get -Headers $script:session -UseBasicParsing
    }
    Process
    {
        # Validate there was information Returned.
        if ($null -ne $ReturnData.value)
        {
            # Grab the data, and Format it in a table.
            $vms = ($ReturnData).value
            $mydata = $vms | Format-Table name, Power_State, cpu_count, memory_size_MiB -AutoSize
            return $mydata
        }
        else
        {
            # Return an error if no data was returned from REST.
            Throw "Get-rVM: Did not recieve a valid response."
        }
    }
}
Write-Verbose 'Importing from [C:\projects\powerrestcli\PowerRestCLI\classes]'