PowerRestCLI.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
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]'