├── .gitattributes ├── .gitignore ├── BloxOne ├── .gitignore ├── BloxOne-DDI │ ├── BloxOne-DDI.Format.ps1xml │ ├── BloxOne-DDI.psd1 │ ├── BloxOne-DDI.psm1 │ ├── BloxOne.code-workspace │ ├── Class │ │ ├── bloxone.psm1 │ │ └── bloxonesession.psm1 │ ├── Private │ │ ├── ConvertTo-URIEncodedFormat.ps1 │ │ ├── Get-IniContent.ps1 │ │ └── Out-IniFile.ps1 │ ├── Public │ │ ├── Get-BaseUrl.ps1 │ │ ├── Get-ConfigInfo.ps1 │ │ └── Get-DDIUrls.ps1 │ ├── bloxone.ini │ ├── class-dev.ps1 │ ├── en-US │ │ └── about_BloxOne-DDI.help.txt │ └── example-crud.ps1 └── Tests │ ├── 000-RunFirst.Tests.ps1 │ ├── 010-Get-ConfigInfo.Tests.ps1 │ ├── 020-Get-BaseUrl.Tests.ps1 │ ├── 025-Get-DDIUrls.Tests.ps1 │ ├── 100-List-DhcpServer.ps1 │ └── bloxone.ini ├── Infoblox-DDI ├── Infoblox-DDI.psd1 ├── Infoblox-DDI.psm1 ├── Infoblox-Get-Request-Format.txt ├── Notes │ └── examples.txt ├── Private │ ├── ConvertFrom-JSON.ps1 │ ├── ConvertTo-JSON.ps1 │ ├── ConvertTo-URIEncodedFormat.ps1 │ ├── Find-Object.ps1 │ ├── Get-Object.ps1 │ ├── IB-ConvertFrom-JSON.ps1 │ ├── IB-ConvertTo-JSON.ps1 │ └── Set-IgnoreSelfSignedCerts.ps1 ├── Public │ ├── Add-ExtensibleAttribute.ps1 │ ├── Connect-GridMaster.ps1 │ ├── Find-Network.ps1 │ ├── Get-Network.ps1 │ ├── Get-Schema.ps1 │ ├── Set-MaxResults.ps1 │ ├── Set-WapiVersion.ps1 │ └── Show-SessionVariables.ps1 └── Sample.ps1 ├── LICENSE ├── README.md ├── examples ├── ib_get-range.ps1 ├── ib_list-ranges.ps1 ├── ib_search.ps1 └── site-creation-in-container.ps1 └── wrapper └── Infoblox.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /BloxOne/.gitignore: -------------------------------------------------------------------------------- 1 | private.ini 2 | b1ddi-class.ps1 3 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/BloxOne-DDI.Format.ps1xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Infoblox-API/PowerShell-OLD/60b2cd0dde9f2d80f84fc05142a0f74daac998af/BloxOne/BloxOne-DDI/BloxOne-DDI.Format.ps1xml -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/BloxOne-DDI.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Infoblox-API/PowerShell-OLD/60b2cd0dde9f2d80f84fc05142a0f74daac998af/BloxOne/BloxOne-DDI/BloxOne-DDI.psd1 -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/BloxOne-DDI.psm1: -------------------------------------------------------------------------------- 1 | # Load class(es) before doing anything else 2 | #Using module ".\Class\bloxonesession.psm1" 3 | #Using module ".\Class\bloxone.psm1" 4 | 5 | 6 | #Requires -Version 7.0 7 | 8 | # Remove the module if loaded so we can reload it 9 | # For debugging and testing purposes 10 | Write-Verbose "Removing old instances of functions" 11 | Get-Module BloxOne-DDI | Remove-Module 12 | 13 | # Get public and private function definition files. 14 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) 15 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) 16 | 17 | # Dot source the files 18 | Foreach($import in @($Public + $Private)) 19 | { 20 | Try 21 | { 22 | . $import.fullname 23 | Write-Debug "Imported function '$($import.fullname)'" 24 | } 25 | Catch 26 | { 27 | Write-Error -Message "Failed to import function $($import.fullname): $_" 28 | } 29 | } 30 | 31 | 32 | # Export everything in the public folder 33 | Export-ModuleMember -Function $Public.Basename 34 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/BloxOne.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "../.." 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Class/bloxone.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7.0 2 | 3 | 4 | # Define the complete list of valid application API URLs 5 | enum appUrls { 6 | host_app 7 | ddi 8 | dns_data #likely an invalid value (converting to ddi.dns.data below per current documentation) 9 | anycast 10 | #atcfw 11 | #atcep 12 | #atcdfp 13 | #atclad 14 | } 15 | 16 | class BloxOne { 17 | # Hide these from general display because of the API key 18 | hidden [string] $apiKey 19 | hidden [hashtable] $headers 20 | 21 | [string] $apiVersion 22 | [string] $baseUrl 23 | 24 | [appUrls] $appUrl 25 | [string] $objectUrl = $null 26 | [psobject] $result = $null 27 | 28 | ################################################ 29 | # Hidden constructors to set defaults where applicable 30 | hidden Init( 31 | [appUrls]$appUrl 32 | ) { 33 | $this.appUrl = $appUrl 34 | } 35 | 36 | ################################################ 37 | # CONSTRUCTORS 38 | 39 | # Default constructor 40 | BloxOne() { 41 | $this.baseUrl = "https://csp.infoblox.com" 42 | $this.apiVersion = "v1" 43 | } 44 | 45 | # Constructor with specific values provided 46 | BloxOne( 47 | [string]$apiKey, 48 | [string]$baseUrl, 49 | [string]$apiVersion 50 | ) 51 | { 52 | $this.SetBaseValues($apiKey, $baseUrl, $apiVersion) 53 | } 54 | 55 | # Constructor with config file and section provided 56 | BloxOne( 57 | [string]$configFile = "bloxone.ini", 58 | [string]$configSection = "BloxOne" 59 | ) 60 | { 61 | [hashtable]$iniConfig = Get-ConfigInfo -configFile $configFile 62 | 63 | # Define the header information 64 | if ($iniConfig.ContainsKey($configSection)) { 65 | $this.SetBaseValues($iniConfig[$configSection].api_key, $iniConfig[$configSection].url, $iniConfig[$configSection].api_Version) 66 | } else { 67 | Write-Warning "The section '$configSection' was not found." 68 | } 69 | } 70 | 71 | # Method to set or update values of key fields 72 | [void] SetBaseValues ( 73 | [string]$apiKey, 74 | [string]$baseUrl, 75 | [string]$apiVersion 76 | ) 77 | { 78 | $this.apiKey = $apiKey 79 | $this.headers = @{"content-type" = "application/json"; "Authorization" = "Token $($this.apiKey)"} 80 | $this.baseUrl = $baseUrl 81 | $this.apiVersion = $apiVersion 82 | } 83 | 84 | # Method override for ToString() 85 | [string] ToString () 86 | { 87 | return "baseUrl: " + $this.baseUrl + ", apiVersion: " + $this.apiVersion 88 | } 89 | 90 | # Perform a GET request without arguments or payload 91 | [boolean] GetRequest ([string] $obj) 92 | { 93 | [string] $urlArgs = $null 94 | [string] $jsonBody = $null 95 | 96 | return $this.GetRequest($obj, $urlArgs, $jsonBody) 97 | } 98 | 99 | # Perform a GET request with arguments 100 | [boolean] GetRequest ([string] $obj, [string] $urlArgs = $null) 101 | { 102 | [string] $jsonBody = $null 103 | 104 | return $this.GetRequest($obj, $urlArgs, $jsonBody) 105 | } 106 | 107 | # Perform a GET request with arguments and a payload 108 | [boolean] GetRequest ([string] $obj, [string] $urlArgs = $null, [string] $jsonBody = $null) 109 | { 110 | # Clear/initialize the result buffer 111 | $this.result = @{} 112 | 113 | # Make sure we have an app API to use 114 | if ([string]::IsNullOrEmpty($this.appUrl)) { 115 | # Eventually change this to an error 116 | Write-Warning "appUrl does not have a value" 117 | return $false 118 | } 119 | 120 | # Verify $obj begins with a "/" 121 | if ($obj -match '^/') { 122 | Write-Verbose "$obj begins with '/'" 123 | } else { 124 | $obj = "/" + $obj 125 | Write-Verbose "$obj updated to include leading '/'" 126 | } 127 | 128 | # Build the object URL or what we are looking for 129 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 130 | 131 | # Add the arguments to the URL 132 | if ([string]::IsNullOrEmpty($urlArgs) -ne $true) { 133 | if ($urlArgs -match '^\?') { 134 | Write-Verbose "$urlArgs begins with '?'" 135 | } else { 136 | $urlArgs = "?" + $urlArgs 137 | $this.objectUrl = $this.objectUrl + $urlArgs 138 | Write-Verbose "$urlArgs updated to include leading '?'" 139 | } 140 | } else { 141 | Write-Verbose "no arguments passed (null or empty)" 142 | } 143 | 144 | Write-Verbose "objectUrl = $($this.objectUrl)" 145 | 146 | # This is for an inherited object but it may be something custom as well 147 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 148 | 149 | try { 150 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 151 | # Branch here if we have a payload to include in the request 152 | [PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers 153 | 154 | # Some results are "result" and some are "results" 155 | if ($data.result.length) { 156 | $this.result = $data.result 157 | } elseif ($data.results.length) { 158 | $this.result = $data.results 159 | } 160 | 161 | } catch { 162 | # Get the actual message from the provider 163 | $reasonPhrase = $_.Exception.Message 164 | Write-Error $reasonPhrase 165 | return $false 166 | } 167 | Write-Verbose "# of results: $($this.result.length)" 168 | 169 | return $true 170 | } 171 | Write-Verbose "objectUrl was empty or null" 172 | return $false 173 | } 174 | 175 | # Perform a POST request with a payload 176 | [boolean] CreateRequest ([string] $obj, [string] $jsonBody) 177 | { 178 | # Clear/initialize the result buffer 179 | $this.result = @{} 180 | 181 | # Make sure we have object data to send 182 | if ([string]::IsNullOrEmpty($jsonBody)) { 183 | # Eventually change this to an error 184 | Write-Warning "object data was not supplied (jsonBody)" 185 | return $false 186 | } 187 | 188 | # Make sure we have an app API to use 189 | if ([string]::IsNullOrEmpty($this.appUrl)) { 190 | # Eventually change this to an error 191 | Write-Warning "appUrl does not have a value" 192 | return $false 193 | } 194 | 195 | # Verify $obj begins with a "/" 196 | if ($obj -match '^/') { 197 | Write-Verbose "$obj begins with '/'" 198 | } else { 199 | $obj = "/" + $obj 200 | Write-Verbose "$obj updated to include leading '/'" 201 | } 202 | 203 | # Build the object URL or what we are looking for 204 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 205 | 206 | Write-Verbose "objectUrl = $($this.objectUrl)" 207 | 208 | # This is for an inherited object but it may be something custom as well 209 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 210 | 211 | try { 212 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 213 | # Branch here if we have a payload to include in the request 214 | [PSObject] $data = Invoke-RestMethod -Method POST -Uri $this.objectUrl -Headers $this.headers -Body $jsonBody 215 | 216 | # Some results are "result" and some are "results" 217 | if ($data.result.length) { 218 | $this.result = $data.result 219 | } elseif ($data.results.length) { 220 | $this.result = $data.results 221 | } 222 | 223 | } catch { 224 | # Get the actual message from the provider 225 | $reasonPhrase = $_.Exception.Message 226 | Write-Error $reasonPhrase 227 | return $false 228 | } 229 | Write-Verbose "# of results: $($this.result.length)" 230 | 231 | return $true 232 | } 233 | Write-Verbose "objectUrl was empty or null" 234 | return $false 235 | } 236 | 237 | # Perform a PATCH request with a payload 238 | [boolean] UpdateRequest ([string] $obj, [string] $jsonBody) 239 | { 240 | # Clear/initialize the result buffer 241 | $this.result = @{} 242 | 243 | # Make sure we have object data to send 244 | if ([string]::IsNullOrEmpty($jsonBody)) { 245 | # Eventually change this to an error 246 | Write-Warning "object data was not supplied (jsonBody)" 247 | return $false 248 | } 249 | 250 | # Make sure we have an app API to use 251 | if ([string]::IsNullOrEmpty($this.appUrl)) { 252 | # Eventually change this to an error 253 | Write-Warning "appUrl does not have a value" 254 | return $false 255 | } 256 | 257 | # Verify $obj begins with a "/" 258 | if ($obj -match '^/') { 259 | Write-Verbose "$obj begins with '/'" 260 | } else { 261 | $obj = "/" + $obj 262 | Write-Verbose "$obj updated to include leading '/'" 263 | } 264 | 265 | # Build the object URL or what we are looking for 266 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 267 | 268 | Write-Verbose "objectUrl = $($this.objectUrl)" 269 | 270 | # This is for an inherited object but it may be something custom as well 271 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 272 | 273 | try { 274 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 275 | # Branch here if we have a payload to include in the request 276 | [PSObject] $data = Invoke-RestMethod -Method PATCH -Uri $this.objectUrl -Headers $this.headers -Body $jsonBody 277 | 278 | # Some results are "result" and some are "results" 279 | if ($data.result.length) { 280 | $this.result = $data.result 281 | } elseif ($data.results.length) { 282 | $this.result = $data.results 283 | } 284 | 285 | } catch { 286 | # Get the actual message from the provider 287 | $reasonPhrase = $_.Exception.Message 288 | Write-Error $reasonPhrase 289 | return $false 290 | } 291 | Write-Verbose "# of results: $($this.result.length)" 292 | 293 | return $true 294 | } 295 | Write-Verbose "objectUrl was empty or null" 296 | return $false 297 | } 298 | 299 | # Perform a DELETE request 300 | [boolean] DeleteRequest ([string] $obj) 301 | { 302 | # Clear/initialize the result buffer 303 | $this.result = @{} 304 | 305 | # Make sure we have an app API to use 306 | if ([string]::IsNullOrEmpty($this.appUrl)) { 307 | # Eventually change this to an error 308 | Write-Warning "appUrl does not have a value" 309 | return $false 310 | } 311 | 312 | # Verify $obj begins with a "/" 313 | if ($obj -match '^/') { 314 | Write-Verbose "$obj begins with '/'" 315 | } else { 316 | $obj = "/" + $obj 317 | Write-Verbose "$obj updated to include leading '/'" 318 | } 319 | 320 | # Build the object URL or what we are looking for 321 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 322 | 323 | Write-Verbose "objectUrl = $($this.objectUrl)" 324 | 325 | # This is for an inherited object but it may be something custom as well 326 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 327 | 328 | try { 329 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 330 | # Branch here if we have a payload to include in the request 331 | [PSObject] $data = Invoke-RestMethod -Method DELETE -Uri $this.objectUrl -Headers $this.headers 332 | 333 | # Some results are "result" and some are "results" 334 | if ($data.result.length) { 335 | $this.result = $data.result 336 | } elseif ($data.results.length) { 337 | $this.result = $data.results 338 | } 339 | 340 | } catch { 341 | # Get the actual message from the provider 342 | $reasonPhrase = $_.Exception.Message 343 | Write-Error $reasonPhrase 344 | return $false 345 | } 346 | Write-Verbose "# of results: $($this.result.length)" 347 | 348 | return $true 349 | } 350 | Write-Verbose "objectUrl was empty or null" 351 | return $false 352 | } 353 | 354 | } 355 | 356 | class OPH : BloxOne { 357 | # Default constructor 358 | OPH() : base() { 359 | $this.Init("host_app") 360 | } 361 | 362 | # Constructor with specific values provided 363 | OPH([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 364 | { 365 | $this.Init("host_app") 366 | } 367 | 368 | # Constructor with config file and section provided 369 | OPH([string]$configFile, [string]$configSection) : base($configFile, $configSection) 370 | { 371 | $this.Init("host_app") 372 | } 373 | } 374 | 375 | class DDI : BloxOne { 376 | # Default constructor 377 | DDI() : base() { 378 | $this.Init("ddi") 379 | } 380 | 381 | # Constructor with specific values provided 382 | DDI([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 383 | { 384 | $this.Init("ddi") 385 | } 386 | 387 | # Constructor with config file and section provided 388 | DDI([string]$configFile, [string]$configSection) : base($configFile, $configSection) 389 | { 390 | $this.Init("ddi") 391 | } 392 | } 393 | 394 | class DNS : BloxOne { 395 | # Default constructor 396 | DNS() : base() { 397 | #$this.Init("dns_data") 398 | $this.Init("ddi") 399 | } 400 | 401 | # Constructor with specific values provided 402 | DNS([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 403 | { 404 | #$this.Init("dns_data") 405 | $this.Init("ddi") 406 | } 407 | 408 | # Constructor with config file and section provided 409 | DNS([string]$configFile, [string]$configSection) : base($configFile, $configSection) 410 | { 411 | #$this.Init("dns_data") 412 | $this.Init("ddi") 413 | } 414 | } -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Class/bloxonesession.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7.0 2 | 3 | class BloxOneSession { 4 | [string] $apiVersion = "v1" 5 | [string] $cspUrl = "https://csp.infoblox.com" 6 | [string] $baseUrl = $null 7 | [string] $apiKey = $null 8 | [hashtable] $headers = @{"content-type" = "application/json"} 9 | [Microsoft.PowerShell.Commands.WebRequestSession] $session = $null 10 | 11 | # Purpose: Establish a connection to CSP and save the session for future use 12 | [void] __INIT__ ($apiKey) { 13 | $this.apiKey = $apiKey 14 | 15 | $this.headers["Authorization"] = "Token $($apiKey)" 16 | $webSession = $null 17 | 18 | $this.baseUrl = $this.cspUrl + "/api/host_app/" + $this.apiVersion + "/" 19 | $objUrl = $this.baseUrl + "on_prem_hosts" 20 | $objArgs = @{"_filter" = "display_name~""/^0/"""} 21 | 22 | Invoke-RestMethod -Method Get -Uri $objUrl -Headers $this.headers -Body $objArgs -SessionVariable webSession 23 | $this.session = $webSession 24 | } 25 | 26 | BloxOneSession ($apiKey) { 27 | $this.__INIT__($apiKey) 28 | } 29 | 30 | BloxOneSession ($apiVersion, $cspUrl, $apiKey) { 31 | $this.apiVersion = $apiVersion 32 | $this.cspUrl = $cspUrl 33 | $this.__INIT__($apiKey) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Private/ConvertTo-URIEncodedFormat.ps1: -------------------------------------------------------------------------------- 1 | function ConvertTo-URIEncodedFormat { 2 | <# 3 | .Synopsis 4 | Encodes the search URI 5 | .Description 6 | Specific characters must be replaced with hex values or WAPI (or PowerShell) may choke. 7 | .Parameter uri_string 8 | A string in WAPI URI compatible format. 9 | .Outputs 10 | Encoded version of the string 11 | .Example 12 | ConvertTo-URIEncodedFormat $my_searchString 13 | #> 14 | 15 | Param ( 16 | [Parameter(Mandatory=$true,Position=0)] 17 | [string]$uri_string 18 | ) 19 | BEGIN { 20 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] Begin" 21 | } 22 | PROCESS { 23 | # Make a copy of the string 24 | $uri = $uri_string 25 | # Replace the with a "%20" 26 | $uri = $uri -replace ' ', "%20" 27 | # Replace the with a "%21" 28 | $uri = $uri -replace '!', "%21" 29 | # Replace the with a "%2A" 30 | #$uri = $uri -replace '*', "%2A" 31 | # Replace the with a "%2B" 32 | $uri = $uri -replace '\+', "%2B" 33 | 34 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] Original: '$uri_string'" 35 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] New : '$uri'" 36 | } 37 | END { 38 | return $uri 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Private/Get-IniContent.ps1: -------------------------------------------------------------------------------- 1 | Function Get-IniContent { 2 | <# 3 | .Synopsis 4 | Gets the content of an INI file 5 | .Description 6 | Gets the content of an INI file and returns it as a hashtable 7 | .Notes 8 | Author : Oliver Lipkau 9 | Source : https://github.com/lipkau/PsIni 10 | http://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8fb-ebd7a76e8d91 11 | Version : 1.0.0 - 2010/03/12 - OL - Initial release 12 | 1.0.1 - 2014/12/11 - OL - Typo (Thx SLDR) 13 | Typo (Thx Dave Stiff) 14 | 1.0.2 - 2015/06/06 - OL - Improvment to switch (Thx Tallandtree) 15 | 1.0.3 - 2015/06/18 - OL - Migrate to semantic versioning (GitHub issue#4) 16 | 1.0.4 - 2015/06/18 - OL - Remove check for .ini extension (GitHub Issue#6) 17 | 1.1.0 - 2015/07/14 - CB - Improve round-tripping and be a bit more liberal (GitHub Pull #7) 18 | OL - Small Improvments and cleanup 19 | 1.1.1 - 2015/07/14 - CB - changed .outputs section to be OrderedDictionary 20 | 1.1.2 - 2016/08/18 - SS - Add some more verbose outputs as the ini is parsed, 21 | allow non-existent paths for new ini handling, 22 | test for variable existence using local scope, 23 | added additional debug output. 24 | #Requires -Version 2.0 25 | .Inputs 26 | System.String 27 | .Outputs 28 | System.Collections.Specialized.OrderedDictionary 29 | .Example 30 | $FileContent = Get-IniContent "C:\myinifile.ini" 31 | ----------- 32 | Description 33 | Saves the content of the c:\myinifile.ini in a hashtable called $FileContent 34 | .Example 35 | $inifilepath | $FileContent = Get-IniContent 36 | ----------- 37 | Description 38 | Gets the content of the ini file passed through the pipe into a hashtable called $FileContent 39 | .Example 40 | C:\PS>$FileContent = Get-IniContent "c:\settings.ini" 41 | C:\PS>$FileContent["Section"]["Key"] 42 | ----------- 43 | Description 44 | Returns the key "Key" of the section "Section" from the C:\settings.ini file 45 | .Link 46 | Out-IniFile 47 | #> 48 | 49 | [CmdletBinding()] 50 | [OutputType( 51 | [System.Collections.Specialized.OrderedDictionary] 52 | )] 53 | Param( 54 | # Specifies the path to the input file. 55 | [ValidateNotNullOrEmpty()] 56 | [Parameter( Mandatory = $true, ValueFromPipeline = $true )] 57 | [String] 58 | $FilePath, 59 | 60 | # Specify what characters should be describe a comment. 61 | # Lines starting with the characters provided will be rendered as comments. 62 | # Default: ";" 63 | [Char[]] 64 | $CommentChar = @(";"), 65 | 66 | # Remove lines determined to be comments from the resulting dictionary. 67 | [Switch] 68 | $IgnoreComments 69 | ) 70 | 71 | Begin { 72 | Write-Debug "PsBoundParameters:" 73 | $PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Debug $_ } 74 | if ($PSBoundParameters['Debug']) { 75 | $DebugPreference = 'Continue' 76 | } 77 | Write-Debug "DebugPreference: $DebugPreference" 78 | 79 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 80 | 81 | $commentRegex = "^\s*([$($CommentChar -join '')].*)$" 82 | $sectionRegex = "^\s*\[(.+)\]\s*$" 83 | $keyRegex = "^\s*(.+?)\s*=\s*(['`"]?)(.*)\2\s*$" 84 | 85 | Write-Debug ("commentRegex is {0}." -f $commentRegex) 86 | } 87 | 88 | Process { 89 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing file: $Filepath" 90 | 91 | $ini = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase) 92 | #$ini = @{} 93 | 94 | if (!(Test-Path $Filepath)) { 95 | Write-Verbose ("Warning: `"{0}`" was not found." -f $Filepath) 96 | Write-Output $ini 97 | } 98 | 99 | $commentCount = 0 100 | switch -regex -file $FilePath { 101 | $sectionRegex { 102 | # Section 103 | $section = $matches[1] 104 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Adding section : $section" 105 | $ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase) 106 | $CommentCount = 0 107 | continue 108 | } 109 | $commentRegex { 110 | # Comment 111 | if (!$IgnoreComments) { 112 | if (!(test-path "variable:local:section")) { 113 | $section = $script:NoSection 114 | $ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase) 115 | } 116 | $value = $matches[1] 117 | $CommentCount++ 118 | Write-Debug ("Incremented CommentCount is now {0}." -f $CommentCount) 119 | $name = "Comment" + $CommentCount 120 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Adding $name with value: $value" 121 | $ini[$section][$name] = $value 122 | } 123 | else { 124 | Write-Debug ("Ignoring comment {0}." -f $matches[1]) 125 | } 126 | 127 | continue 128 | } 129 | $keyRegex { 130 | # Key 131 | if (!(test-path "variable:local:section")) { 132 | $section = $script:NoSection 133 | $ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase) 134 | } 135 | $name, $value = $matches[1, 3] 136 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Adding key $name with value: $value" 137 | if (-not $ini[$section][$name]) { 138 | $ini[$section][$name] = $value 139 | } 140 | else { 141 | if ($ini[$section][$name] -is [string]) { 142 | $ini[$section][$name] = [System.Collections.ArrayList]::new() 143 | $ini[$section][$name].Add($ini[$section][$name]) | Out-Null 144 | $ini[$section][$name].Add($value) | Out-Null 145 | } 146 | else { 147 | $ini[$section][$name].Add($value) | Out-Null 148 | } 149 | } 150 | continue 151 | } 152 | } 153 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Processing file: $FilePath" 154 | Write-Output $ini 155 | } 156 | 157 | End { 158 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended" 159 | } 160 | } 161 | 162 | Set-Alias gic Get-IniContent -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Private/Out-IniFile.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Infoblox-API/PowerShell-OLD/60b2cd0dde9f2d80f84fc05142a0f74daac998af/BloxOne/BloxOne-DDI/Private/Out-IniFile.ps1 -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Public/Get-BaseUrl.ps1: -------------------------------------------------------------------------------- 1 | Function Get-BaseUrl { 2 |     <# 3 |     .Synopsis 4 |       Constructs the BaseURL for a select API call 5 | 6 |     .Description 7 |         Creates the base URL for the specific application API call 8 | 9 |     .Notes 10 |         Author      : Don Smith 11 |         Version     : 1.0 - 2020-07-29 - Initial release 12 | : 1.1 - 2020-08-04 - Added ValidateSet for the cspApp 13 | : 1.2 - 2020-08-05 - Added 'anycast' to the ValidateSet 14 | 15 |     .Inputs 16 |         CSP BaseURL as System.String 17 | Application as System.String 18 | API Version as System.String 19 | 20 |     .Outputs 21 |         baseUrl as System.String 22 | 23 |     .Parameter cspBaseUrl 24 |         Specifies the URI path to the Cloud Services Portal (CSP). 25 | Defaults to "https://csp.infoblox.com" 26 | 27 | .Parameter cspApp 28 | Specifies the app where the data is hosted 29 | Required as input 30 | 31 | .Parameter apiVersion 32 | Specifies the API version 33 | Defaults to "v1" 34 | 35 |     .Example 36 |         $baseUrl = Get-BaseUrl "https://csp.infoblox.com/" "ddi" "v1" 37 |         ----------- 38 |         Description 39 |         Accesses the production CSP system, DDI application, using API version 1 40 | 41 |     .Example 42 |         $baseUrl = Get-BaseUrl -cspApp "ddi" 43 |         ----------- 44 |         Description 45 |         Accesses the production CSP system, DDI application, using API version 1 46 | 47 |     .Link 48 |         Get-BaseUrl 49 |     #> 50 | 51 | [CmdletBinding()] 52 | Param( 53 | 54 | [Parameter(Mandatory=$False,Position=0)]   55 | [string]$cspBaseUrl = "https://csp.infoblox.com", 56 | 57 | [Parameter(Mandatory=$True,Position=1)] 58 | [ValidateSet('ddi','ddi.dns.data','host_app','anycast')]  59 | [string]$cspApp, 60 | 61 | [Parameter(Mandatory=$False,Position=2)]   62 | [string]$apiVersion = "v1" 63 |     ) 64 | 65 | BEGIN { 66 | Write-Debug "PsBoundParameters:" 67 | $PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Debug $_ } 68 | if ($PSBoundParameters['Debug']) { 69 | $DebugPreference = 'Continue' 70 | } 71 | Write-Debug "DebugPreference: $DebugPreference" 72 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 73 | 74 | # Build the complete base API URL with the supplied information 75 | $baseUrl = "$cspBaseUrl/api/$cspApp/$apiVersion" 76 | Write-Verbose "baseUrl = $baseUrl" 77 | } 78 | 79 | PROCESS { 80 | #Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing" 81 | } 82 | 83 | END { 84 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended" 85 | return $baseUrl 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Public/Get-ConfigInfo.ps1: -------------------------------------------------------------------------------- 1 | Function Get-ConfigInfo { 2 | <# 3 | .Synopsis 4 | Reads the config info from the provided INI file 5 | 6 | .Description 7 | Accepts a passed INI file or will read the bloxone.ini file in the current directory. 8 | If [Private] is found with a path key, the one additional INI file will be read. 9 | 10 |     .Notes 11 | Author      : Don Smith 12 | Version     : 1.0 - 2020-07-30 - Initial release 13 | 14 |     .Inputs 15 | configFile as System.String 16 | 17 |     .Outputs 18 | iniConfig as System.Collections.Specialized.OrderedDictionary 19 | 20 |     .Parameter iniFileName 21 | Specifies the filename of the INI file to read 22 | Defaults to ".\bloxone.ini" 23 | 24 |     .Example 25 | $iniConfig = Get-ConfigInfo "custom.ini" 26 | ----------- 27 | Description 28 | Reads the custom.ini file in the local directory 29 | 30 |     .Example 31 | $iniConfig = Get-ConfigInfo 32 | ----------- 33 | Description 34 | Reads the bloxone.ini file in the local directory 35 | 36 |     .Link 37 | Get-ConfigInfo 38 |     #> 39 | 40 | [CmdletBinding()] 41 | Param( 42 | 43 | [Parameter(ValueFromPipeline=$True,Mandatory=$False,Position=0)] 44 | [string]$configFile = "bloxone.ini", 45 | 46 | # Tells us not to create the INI file if we don't find it 47 | [switch] 48 | $DoNotCreate 49 |     ) 50 | 51 | BEGIN { 52 | Write-Debug "PsBoundParameters:" 53 | $PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Debug $_ } 54 | if ($PSBoundParameters['Debug']) { 55 | $DebugPreference = 'Continue' 56 | } 57 | Write-Debug "DebugPreference: $DebugPreference" 58 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 59 | 60 | # Check to make sure the file exists 61 | if (Test-Path $configFile) { 62 | Write-Debug "$($MyInvocation.MyCommand.Name):: Found $configFile" 63 | 64 | [hashtable]$iniConfig = Get-IniContent $configFile 65 | 66 | # See if we need to load an additional INI file 67 | if ($iniConfig.Contains("Private")) { 68 | # Make sure the file exists that we are looking for 69 | $privateFileName = $iniConfig["Private"].path 70 | if (Test-Path $privateFileName) { 71 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Attempting to load alternate INI file $privateFileName" 72 | [hashtable]$privateConfig = (Get-IniContent $privateFileName) 73 | 74 | # Combine the results from the two files but use the second file as a authoritative value set 75 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Combining INI configs ($configFile and $privateFileName)" 76 | foreach ($key in $privateConfig.Keys) { 77 | $iniConfig[$key] = $privateConfig[$key] 78 | } 79 | $iniConfig.Remove("Private") 80 | } else { 81 | Write-Debug "Alternate INI file specified not found" 82 | } 83 | } 84 | } else { 85 | Write-Warning "$configFile was not found" 86 | 87 | if (!$DoNotCreate) { 88 | # Create a template INI file since one did not exist 89 | $iniSection = @{“url”=”https://csp.infoblox.com”;”api_version”=”v1”;"api_key"=""} 90 | $iniContent = @{“BloxOne”=$iniSection} 91 | Out-IniFile -InputObject $iniContent -FilePath $configFile -Loose -Pretty 92 | 93 | $iniConfig = Get-ConfigInfo $configFile -DoNotCreate 94 | } 95 | } 96 | } 97 | 98 | PROCESS { 99 | #Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing" 100 | } 101 | 102 | END { 103 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended" 104 | return $iniConfig 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/Public/Get-DDIUrls.ps1: -------------------------------------------------------------------------------- 1 | Function Get-DDIUrls { 2 | <# 3 | .Synopsis 4 | Constructs the BaseURL for all BloxOne API calls 5 | 6 | .Description 7 | Creates the base URL for all application specific API calls 8 | 9 | .Notes 10 | Author : Don Smith 11 | Version : 1.0 - 2020-07-29 - Initial release 12 | : 1.1 - 2020-08-04 - Cleaned up notes 13 | : 1.2 - 2020-08-05 - Added 'anycastUrl' as an additional return item 14 | 15 | .Inputs 16 | CSP Hostname URI as String 17 | API Version as String 18 | iniConfig as hashtable 19 | iniSection as String 20 | 21 | .Outputs 22 | System.Collections.Specialized.OrderedDictionary 23 | 24 | .Parameter cspBaseUrl 25 | Specifies the URI paths for all APIs to the Cloud Services Portal (CSP). 26 | Defaults to "https://csp.infoblox.com" 27 | 28 | .Parameter apiVersion 29 | Specifies the API version 30 | Defaults to "v1" 31 | 32 | .Parameter iniConfig 33 | Provides the Config hashtable 34 | Requires iniSection to be provided as well 35 | 36 | .Parameter iniSection 37 | Specifies the section in the config hashtable to use 38 | Requires iniConfig to be provided as well 39 | 40 | .Example 41 | [hashtable]$cspUrls = Get-DDIUrls "https://csp.infoblox.com/" "v1" 42 | ----------- 43 | Description 44 | Accesses the production CSP system, all applications, using API version 1 45 | 46 | .Example 47 | $cspUrls = Get-DDIUrls 48 | ----------- 49 | Description 50 | Accesses the production CSP system, all applications, using API version 1 51 | 52 | .Example 53 | $cspUrls = Get-DDIUrls -iniConfig $iniConfig -iniSection "Sample" 54 | ----------- 55 | Description 56 | Accesses the production CSP system, all applications, using API version 1 57 | 58 | .Link 59 | Get-DDIUrls 60 | #> 61 | 62 | [CmdletBinding()] 63 | Param( 64 | [Parameter(ValueFromPipeline=$True,Mandatory=$False,Position=0)]   65 | [string]$cspBaseUrl = "https://csp.infoblox.com", 66 | 67 | [Parameter(ValueFromPipeline=$True,Mandatory=$False,Position=1)]   68 | [string]$apiVersion = "v1", 69 | 70 | [Parameter(Mandatory=$False)] 71 | [hashtable]$iniConfig, 72 | 73 | [Parameter(Mandatory=$False)] 74 | [string]$iniSection 75 |     ) 76 | 77 | BEGIN { 78 | Write-Debug "PsBoundParameters:" 79 | $PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Debug $_ } 80 | if ($PSBoundParameters['Debug']) { 81 | $DebugPreference = 'Continue' 82 | } 83 | Write-Debug "DebugPreference: $DebugPreference" 84 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started" 85 | 86 | 87 | # Build the list of apps that will be needed for creating the URLs 88 | [hashtable]$cspApps = @{ipamUrl = "ddi"; dnsAppUrl = "ddi.dns.data"; hostAppUrl = "host_app"; anycastUrl = "anycast"} 89 | 90 | # See if we were passed an INI file and section 91 | if (($PSBoundParameters.ContainsKey('iniConfig') -eq $True) -and ($PSBoundParameters.ContainsKey('iniSection') -eq $True)) { 92 | # Look for the section inside the config to grab the cspHostname and apiVersion 93 | Write-Verbose "$($MyInvocation.MyCommand.Name):: iniConfig and iniSection provided" 94 | if ($iniConfig.Contains($iniSection) -eq $True) { 95 | 96 | # The section exists, now grab the values temporarily 97 | $tempUrl = $iniConfig.($iniSection).url 98 | $tempApiVersion = $iniConfig.($iniSection).api_version 99 | Write-Verbose "$($MyInvocation.MyCommand.Name)>> config section variables { $tempUrl, $tempApiVersion }" 100 | 101 | # If explicitly passed, we will use the cspHostname provided 102 | if ($PsBoundParameters.ContainsKey('cspBaseUrl') -eq $False) { 103 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Updating cspBaseUrl with $tempUrl" 104 | $cspBaseUrl = $tempUrl 105 | } 106 | 107 | # If explicitly passed, we will use the apiVersion provided 108 | if ($PsBoundParameters.ContainsKey('apiVersion') -eq $False) { 109 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Updating apiVersion with $tempApiVersion" 110 | $apiVersion = $tempApiVersion 111 | } 112 | 113 | } else { 114 | # The section does not exist 115 | Write-Error "$iniSection does not exist in the INI Config data" 116 | } 117 | } else { 118 | Write-Verbose "$($MyInvocation.MyCommand.Name):: no iniConfig and/or iniSection" 119 | } 120 | 121 | # Loop through the apps and create the Url 122 | [hashtable]$hashUrl = @{} 123 | 124 | $cspApps.GetEnumerator() | ForEach-Object { 125 | # Store the values to work with later 126 | $keyName = $_.Name 127 | $appName = $_.Value 128 | 129 | # Build the URL for the specific app 130 | Write-Debug "calling out to Get-BaseUrl" 131 | $appUrl = Get-BaseUrl -cspBaseUrl $cspBaseUrl -cspApp $appName -apiVersion $apiVersion 132 | Write-Debug "returned from Get-BaseUrl" 133 | Write-Verbose "$($MyInvocation.MyCommand.Name)>> key = $keyName, app = $appName, url = $appUrl" 134 | 135 | # Add the app URL to the app so we can index it later 136 | $hashUrl[$keyName] = $appUrl 137 | } 138 | 139 | } 140 | 141 | PROCESS { 142 | #Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing" 143 | } 144 | 145 | END { 146 | Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended" 147 | return [hashtable]$hashUrl; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/bloxone.ini: -------------------------------------------------------------------------------- 1 | # INI Sample File 2 | # 3 | # Consider a configuration file to read basic info from 4 | # This is INI format to match Chris Marrison’s setup 5 | # Might consider doing this is JSON 6 | # Filename could be passed and/or section to read could be passed 7 | # Do not quote the values 8 | # 9 | [AMS] 10 | url = https://csp.infoblox.com 11 | api_version = v1 12 | api_key = 13 | 14 | [Private] 15 | # path to private INI file with real API keys 16 | # reserved heading 17 | path = private.ini 18 | 19 | [BloxOne] 20 | url = https://bloxone.csp.infoblox.com 21 | api_key = 22 | api_version = v1 23 | -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/class-dev.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7.0 2 | 3 | ### Sample PowerShell Script for BloxOne DDI 4 | ### Author: Don Smith 5 | ### Author-Email: dsmith@infoblox.com 6 | 7 | #Using module ".\Class\bloxone.psm1" 8 | $VerbosePreference = 'continue' 9 | #$VerbosePreference = 'SilentlyContinue' 10 | 11 | # Remove old functions/Cmdlets from the current module 12 | Write-Output "Removing old instances of functions" 13 | Get-Module BloxOne-DDI | Remove-Module 14 | clear 15 | 16 | # Load the current module 17 | Import-Module “.\BloxOne-DDI.psd1” 18 | 19 | class BloxOneSession { 20 | [string] $apiVersion = "v1" 21 | [string] $cspUrl = "https://csp.infoblox.com" 22 | [string] $baseUrl = $null 23 | [string] $apiKey = $null 24 | [hashtable] $headers = @{"content-type" = "application/json"} 25 | [Microsoft.PowerShell.Commands.WebRequestSession] $session = $null 26 | 27 | # Purpose: Establish a connection to CSP and save the session for future use 28 | [void] __INIT__ ($apiKey) { 29 | $this.apiKey = $apiKey 30 | 31 | $this.headers["Authorization"] = "Token $($apiKey)" 32 | $webSession = $null 33 | 34 | $this.baseUrl = $this.cspUrl + "/api/host_app/" + $this.apiVersion + "/" 35 | $objUrl = $this.baseUrl + "on_prem_hosts" 36 | $objArgs = @{"_filter" = "display_name~""/^0/"""} 37 | 38 | Invoke-RestMethod -Method Get -Uri $objUrl -Headers $this.headers -Body $objArgs -SessionVariable webSession 39 | $this.session = $webSession 40 | } 41 | 42 | BloxOneSession ($apiKey) { 43 | $this.__INIT__($apiKey) 44 | } 45 | 46 | BloxOneSession ($apiVersion, $cspUrl, $apiKey) { 47 | $this.apiVersion = $apiVersion 48 | $this.cspUrl = $cspUrl 49 | $this.__INIT__($apiKey) 50 | } 51 | } 52 | 53 | 54 | # Define the complete list of valid application API URLs 55 | enum appUrls { 56 | host_app 57 | ddi 58 | dns_data #likely an invalid value (converting to ddi.dns.data below per current documentation) 59 | anycast 60 | #atcfw 61 | #atcep 62 | #atcdfp 63 | #atclad 64 | } 65 | 66 | class BloxOne { 67 | # Hide these from general display because of the API key 68 | hidden [string] $apiKey 69 | hidden [hashtable] $headers 70 | 71 | [string] $apiVersion 72 | [string] $baseUrl 73 | 74 | [appUrls] $appUrl 75 | [string] $objectUrl = $null 76 | [psobject] $result = $null 77 | 78 | ################################################ 79 | # Hidden constructors to set defaults where applicable 80 | hidden Init( 81 | [appUrls]$appUrl 82 | ) { 83 | $this.appUrl = $appUrl 84 | } 85 | 86 | ################################################ 87 | # CONSTRUCTORS 88 | 89 | # Default constructor 90 | BloxOne() { 91 | $this.baseUrl = "https://csp.infoblox.com" 92 | $this.apiVersion = "v1" 93 | } 94 | 95 | # Constructor with specific values provided 96 | BloxOne( 97 | [string]$apiKey, 98 | [string]$baseUrl, 99 | [string]$apiVersion 100 | ) 101 | { 102 | $this.SetBaseValues($apiKey, $baseUrl, $apiVersion) 103 | } 104 | 105 | # Constructor with config file and section provided 106 | BloxOne( 107 | [string]$configFile = "bloxone.ini", 108 | [string]$configSection = "BloxOne" 109 | ) 110 | { 111 | [hashtable]$iniConfig = Get-ConfigInfo -configFile $configFile 112 | 113 | # Define the header information 114 | if ($iniConfig.ContainsKey($configSection)) { 115 | $this.SetBaseValues($iniConfig[$configSection].api_key, $iniConfig[$configSection].url, $iniConfig[$configSection].api_Version) 116 | } else { 117 | Write-Warning "The section '$configSection' was not found." 118 | } 119 | } 120 | 121 | # Method to set or update values of key fields 122 | [void] SetBaseValues ( 123 | [string]$apiKey, 124 | [string]$baseUrl, 125 | [string]$apiVersion 126 | ) 127 | { 128 | $this.apiKey = $apiKey 129 | $this.headers = @{"content-type" = "application/json"; "Authorization" = "Token $($this.apiKey)"} 130 | $this.baseUrl = $baseUrl 131 | $this.apiVersion = $apiVersion 132 | } 133 | 134 | # Method override for ToString() 135 | [string] ToString () 136 | { 137 | return "baseUrl: " + $this.baseUrl + ", apiVersion: " + $this.apiVersion 138 | } 139 | 140 | # Perform a GET request without arguments or payload 141 | [boolean] GetRequest ([string] $obj) 142 | { 143 | [string] $urlArgs = $null 144 | [string] $jsonBody = $null 145 | 146 | return $this.GetRequest($obj, $urlArgs, $jsonBody) 147 | } 148 | 149 | # Perform a GET request with arguments 150 | [boolean] GetRequest ([string] $obj, [string] $urlArgs = $null) 151 | { 152 | [string] $jsonBody = $null 153 | 154 | return $this.GetRequest($obj, $urlArgs, $jsonBody) 155 | } 156 | 157 | # Perform a GET request with arguments and a payload 158 | [boolean] GetRequest ([string] $obj, [string] $urlArgs = $null, [string] $jsonBody = $null) 159 | { 160 | # Clear/initialize the result buffer 161 | $this.result = @{} 162 | 163 | # Make sure we have an app API to use 164 | if ([string]::IsNullOrEmpty($this.appUrl)) { 165 | # Eventually change this to an error 166 | Write-Warning "appUrl does not have a value" 167 | return $false 168 | } 169 | 170 | # Verify $obj begins with a "/" 171 | if ($obj -match '^/') { 172 | Write-Verbose "$obj begins with '/'" 173 | } else { 174 | $obj = "/" + $obj 175 | Write-Verbose "$obj updated to include leading '/'" 176 | } 177 | 178 | # Build the object URL or what we are looking for 179 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 180 | 181 | # Add the arguments to the URL 182 | if ([string]::IsNullOrEmpty($urlArgs) -ne $true) { 183 | if ($urlArgs -match '^\?') { 184 | Write-Verbose "$urlArgs begins with '?'" 185 | } else { 186 | $urlArgs = "?" + $urlArgs 187 | $this.objectUrl = $this.objectUrl + $urlArgs 188 | Write-Verbose "$urlArgs updated to include leading '?'" 189 | } 190 | } else { 191 | Write-Verbose "no arguments passed (null or empty)" 192 | } 193 | 194 | Write-Verbose "objectUrl = $($this.objectUrl)" 195 | 196 | # This is for an inherited object but it may be something custom as well 197 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 198 | 199 | try { 200 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 201 | # Branch here if we have a payload to include in the request 202 | [PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers 203 | 204 | # Some results are "result" and some are "results" 205 | if ($data.result.length) { 206 | $this.result = $data.result 207 | } elseif ($data.results.length) { 208 | $this.result = $data.results 209 | } 210 | 211 | } catch { 212 | # Get the actual message from the provider 213 | $reasonPhrase = $_.Exception.Message 214 | Write-Error $reasonPhrase 215 | return $false 216 | } 217 | Write-Verbose "# of results: $($this.result.length)" 218 | 219 | return $true 220 | } 221 | Write-Verbose "objectUrl was empty or null" 222 | return $false 223 | } 224 | 225 | # Perform a POST request with a payload 226 | [boolean] CreateRequest ([string] $obj, [string] $jsonBody) 227 | { 228 | # Clear/initialize the result buffer 229 | $this.result = @{} 230 | 231 | # Make sure we have object data to send 232 | if ([string]::IsNullOrEmpty($jsonBody)) { 233 | # Eventually change this to an error 234 | Write-Warning "object data was not supplied (jsonBody)" 235 | return $false 236 | } 237 | 238 | # Make sure we have an app API to use 239 | if ([string]::IsNullOrEmpty($this.appUrl)) { 240 | # Eventually change this to an error 241 | Write-Warning "appUrl does not have a value" 242 | return $false 243 | } 244 | 245 | # Verify $obj begins with a "/" 246 | if ($obj -match '^/') { 247 | Write-Verbose "$obj begins with '/'" 248 | } else { 249 | $obj = "/" + $obj 250 | Write-Verbose "$obj updated to include leading '/'" 251 | } 252 | 253 | # Build the object URL or what we are looking for 254 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 255 | 256 | Write-Verbose "objectUrl = $($this.objectUrl)" 257 | 258 | # This is for an inherited object but it may be something custom as well 259 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 260 | 261 | try { 262 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 263 | # Branch here if we have a payload to include in the request 264 | [PSObject] $data = Invoke-RestMethod -Method POST -Uri $this.objectUrl -Headers $this.headers -Body $jsonBody 265 | 266 | # Some results are "result" and some are "results" 267 | if ($data.result.length) { 268 | $this.result = $data.result 269 | } elseif ($data.results.length) { 270 | $this.result = $data.results 271 | } 272 | 273 | } catch { 274 | # Get the actual message from the provider 275 | $reasonPhrase = $_.Exception.Message 276 | Write-Error $reasonPhrase 277 | return $false 278 | } 279 | Write-Verbose "# of results: $($this.result.length)" 280 | 281 | return $true 282 | } 283 | Write-Verbose "objectUrl was empty or null" 284 | return $false 285 | } 286 | 287 | # Perform a PATCH request with a payload 288 | [boolean] UpdateRequest ([string] $obj, [string] $jsonBody) 289 | { 290 | # Clear/initialize the result buffer 291 | $this.result = @{} 292 | 293 | # Make sure we have object data to send 294 | if ([string]::IsNullOrEmpty($jsonBody)) { 295 | # Eventually change this to an error 296 | Write-Warning "object data was not supplied (jsonBody)" 297 | return $false 298 | } 299 | 300 | # Make sure we have an app API to use 301 | if ([string]::IsNullOrEmpty($this.appUrl)) { 302 | # Eventually change this to an error 303 | Write-Warning "appUrl does not have a value" 304 | return $false 305 | } 306 | 307 | # Verify $obj begins with a "/" 308 | if ($obj -match '^/') { 309 | Write-Verbose "$obj begins with '/'" 310 | } else { 311 | $obj = "/" + $obj 312 | Write-Verbose "$obj updated to include leading '/'" 313 | } 314 | 315 | # Build the object URL or what we are looking for 316 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 317 | 318 | Write-Verbose "objectUrl = $($this.objectUrl)" 319 | 320 | # This is for an inherited object but it may be something custom as well 321 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 322 | 323 | try { 324 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 325 | # Branch here if we have a payload to include in the request 326 | [PSObject] $data = Invoke-RestMethod -Method PATCH -Uri $this.objectUrl -Headers $this.headers -Body $jsonBody 327 | 328 | # Some results are "result" and some are "results" 329 | if ($data.result.length) { 330 | $this.result = $data.result 331 | } elseif ($data.results.length) { 332 | $this.result = $data.results 333 | } 334 | 335 | } catch { 336 | # Get the actual message from the provider 337 | $reasonPhrase = $_.Exception.Message 338 | Write-Error $reasonPhrase 339 | return $false 340 | } 341 | Write-Verbose "# of results: $($this.result.length)" 342 | 343 | return $true 344 | } 345 | Write-Verbose "objectUrl was empty or null" 346 | return $false 347 | } 348 | 349 | # Perform a DELETE request 350 | [boolean] DeleteRequest ([string] $obj) 351 | { 352 | # Clear/initialize the result buffer 353 | $this.result = @{} 354 | 355 | # Make sure we have an app API to use 356 | if ([string]::IsNullOrEmpty($this.appUrl)) { 357 | # Eventually change this to an error 358 | Write-Warning "appUrl does not have a value" 359 | return $false 360 | } 361 | 362 | # Verify $obj begins with a "/" 363 | if ($obj -match '^/') { 364 | Write-Verbose "$obj begins with '/'" 365 | } else { 366 | $obj = "/" + $obj 367 | Write-Verbose "$obj updated to include leading '/'" 368 | } 369 | 370 | # Build the object URL or what we are looking for 371 | $this.objectUrl = $this.baseUrl + "/api/" + $this.appUrl + "/" + $this.apiVersion + "$obj" 372 | 373 | Write-Verbose "objectUrl = $($this.objectUrl)" 374 | 375 | # This is for an inherited object but it may be something custom as well 376 | if ([string]::IsNullOrEmpty($this.objectUrl) -ne $true ) { 377 | 378 | try { 379 | #[PSObject] $data = Invoke-RestMethod -Method Get -Uri $this.objectUrl -Headers $this.headers -ContentType "application/json" 380 | # Branch here if we have a payload to include in the request 381 | [PSObject] $data = Invoke-RestMethod -Method DELETE -Uri $this.objectUrl -Headers $this.headers 382 | 383 | # Some results are "result" and some are "results" 384 | if ($data.result.length) { 385 | $this.result = $data.result 386 | } elseif ($data.results.length) { 387 | $this.result = $data.results 388 | } 389 | 390 | } catch { 391 | # Get the actual message from the provider 392 | $reasonPhrase = $_.Exception.Message 393 | Write-Error $reasonPhrase 394 | return $false 395 | } 396 | Write-Verbose "# of results: $($this.result.length)" 397 | 398 | return $true 399 | } 400 | Write-Verbose "objectUrl was empty or null" 401 | return $false 402 | } 403 | 404 | } 405 | 406 | class OPH : BloxOne { 407 | # Default constructor 408 | OPH() : base() { 409 | $this.Init("host_app") 410 | } 411 | 412 | # Constructor with specific values provided 413 | OPH([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 414 | { 415 | $this.Init("host_app") 416 | } 417 | 418 | # Constructor with config file and section provided 419 | OPH([string]$configFile, [string]$configSection) : base($configFile, $configSection) 420 | { 421 | $this.Init("host_app") 422 | } 423 | } 424 | 425 | class DDI : BloxOne { 426 | # Default constructor 427 | DDI() : base() { 428 | $this.Init("ddi") 429 | } 430 | 431 | # Constructor with specific values provided 432 | DDI([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 433 | { 434 | $this.Init("ddi") 435 | } 436 | 437 | # Constructor with config file and section provided 438 | DDI([string]$configFile, [string]$configSection) : base($configFile, $configSection) 439 | { 440 | $this.Init("ddi") 441 | } 442 | } 443 | 444 | class DNS : BloxOne { 445 | # Default constructor 446 | DNS() : base() { 447 | #$this.Init("dns_data") 448 | $this.Init("ddi") 449 | } 450 | 451 | # Constructor with specific values provided 452 | DNS([string]$apiKey, [string]$baseUrl, [string]$apiVersion) : base($apiKey, $baseUrl, $apiVersion) 453 | { 454 | #$this.Init("dns_data") 455 | $this.Init("ddi") 456 | } 457 | 458 | # Constructor with config file and section provided 459 | DNS([string]$configFile, [string]$configSection) : base($configFile, $configSection) 460 | { 461 | #$this.Init("dns_data") 462 | $this.Init("ddi") 463 | } 464 | } 465 | 466 | 467 | #-------------------- 468 | # Test Code 469 | #-------------------- 470 | 471 | <# 472 | $session1 = [BloxOneSession]::New("***api_key***") 473 | $session1 474 | #> 475 | 476 | 477 | Write-Output "<<----- [ddi3] ---------------------------------------->>" 478 | Write-Output "DDI object with INI file and section" 479 | $ddi3 = [DDI]::New("bloxone.ini", "Sandbox") 480 | 481 | # Create a new object 482 | $newObjJson = "{ ""name"":""delete_me"", ""comment"":""Created via PowerShell script"" }" 483 | $newObjType = "/ipam/ip_space" 484 | $ddi3.CreateRequest($newObjType, $newObjJson) 485 | 486 | # Retrieve the object 487 | $ddi3_args = "_fields=name,comment,id,tags&_filter=name==""delete_me""" 488 | $ddi3.GetRequest("/ipam/ip_space", $ddi3_args) 489 | $objID = $ddi3.result[0].id 490 | 491 | # Update the object 492 | $newObjJson = "{ ""name"":""patched_me"", ""comment"":""Updated via PowerShell script"" }" 493 | $ddi3.UpdateRequest($objID, $newObjJson) 494 | 495 | # Delete the object 496 | $ddi3.DeleteRequest($objID) 497 | 498 | <# 499 | 500 | # _filter=name=="dsmith-fusion-network1" 501 | # _fields=name,comment,id,tags 502 | Write-Output "<<----- [ddi4] ---------------------------------------->>" 503 | #$ddi4 = [DDI]::New("bloxone.ini", "Sandbox") 504 | $ddi4 = [DDI]::New($ddi3.apiKey, $ddi3.baseUrl, $ddi3.urlVersion) 505 | $ddi4_args = "_fields=name,comment,id,tags&_filter=name==""dsmith-fusion-network1""" 506 | $ddi4.GetRequest("/ipam/ip_space", $ddi4_args) 507 | $ddi4 508 | 509 | 510 | Write-Output "<<----- [dns1] ---------------------------------------->>" 511 | Write-Output "DNS object with INI file and section" 512 | $dns1 = [DNS]::New("bloxone.ini", "Sandbox") 513 | Write-Output "DNS: values = " 514 | $dns1 515 | Write-Output "DNS: GET" 516 | $dns1.GetRequest("/dns/record") 517 | #$dns1.result 518 | 519 | 520 | <# 521 | # Create an object using our BloxOne class 522 | $b1 = [BloxOne]::New() 523 | $b1 524 | $b1.SetBaseValues("abcdefg", "https://something.csp.infoblox.com", "v99") 525 | $b1 526 | 527 | $b3 = [BloxOne]::New("a123456", "https://awesome.csp.infoblox.com", "v5") 528 | $b3 529 | #> 530 | 531 | 532 | 533 | #> -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/en-US/about_BloxOne-DDI.help.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Infoblox-API/PowerShell-OLD/60b2cd0dde9f2d80f84fc05142a0f74daac998af/BloxOne/BloxOne-DDI/en-US/about_BloxOne-DDI.help.txt -------------------------------------------------------------------------------- /BloxOne/BloxOne-DDI/example-crud.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7.0 2 | 3 | ### Sample PowerShell Script for BloxOne DDI 4 | ### Author: Don Smith 5 | ### Author-Email: dsmith@infoblox.com 6 | 7 | Using module ".\Class\bloxonesession.psm1" 8 | Using module ".\Class\bloxone.psm1" 9 | $VerbosePreference = 'continue' 10 | #$VerbosePreference = 'SilentlyContinue' 11 | 12 | # Remove old functions/Cmdlets from the current module 13 | Write-Output "Removing old instances of functions" 14 | Get-Module BloxOne-DDI | Remove-Module 15 | clear 16 | 17 | # Load the current module 18 | Import-Module “.\BloxOne-DDI.psd1” 19 | 20 | 21 | #-------------------- 22 | # Test Code 23 | #-------------------- 24 | 25 | <# 26 | # Create a reusable session 27 | $session1 = [BloxOneSession]::New("***api_key***") 28 | $session1 29 | #> 30 | 31 | Write-Output "<<----- [ddi1] ---------------------------------------->>" 32 | Write-Output "DDI object with INI file and section" 33 | $ddi1 = [DDI]::New("bloxone.ini", "Sandbox") 34 | 35 | # Create a new object 36 | $newObjJson = "{ ""name"":""delete_me"", ""comment"":""Created via PowerShell script"" }" 37 | $newObjType = "/ipam/ip_space" 38 | $ddi1.CreateRequest($newObjType, $newObjJson) 39 | 40 | # Retrieve the object 41 | $ddi1_args = "_fields=name,comment,id,tags&_filter=name==""delete_me""" 42 | $ddi1.GetRequest("/ipam/ip_space", $ddi1_args) 43 | $objID = $ddi1.result[0].id 44 | 45 | # Update the object 46 | $newObjJson = "{ ""name"":""patched_me"", ""comment"":""Updated via PowerShell script"" }" 47 | $ddi1.UpdateRequest($objID, $newObjJson) 48 | 49 | # Delete the object 50 | $ddi1.DeleteRequest($objID) 51 | -------------------------------------------------------------------------------- /BloxOne/Tests/000-RunFirst.Tests.ps1: -------------------------------------------------------------------------------- 1 | # Requires -Version 7 2 | ### Sample PowerShell Script for BloxOne DDI 3 | ### Author: Don Smith 4 | ### Author-Email: dsmith@infoblox.com 5 | ### Version: 2020-08-03 Initial release 6 | 7 | #$DebugPreference = 'continue' 8 | $VerbosePreference = 'continue' 9 | 10 | # Remove the module if loaded so we can reload it 11 | # For debugging and testing purposes 12 | Write-OutPut "Removing old instances of public functions" 13 | Get-Module BloxOne-DDI | Remove-Module 14 | 15 | # Store locations for the module, tests, and parent directories 16 | $testDir = Get-Location 17 | $parentDir = (get-item $testDir).parent.FullName 18 | $scriptDir = "$parentDir\BloxOne-DDI" 19 | @{ "parentDir" = $parentDir; "testDir" = $testDir; "scriptDir" = $scriptDir} | Write-OutPut 20 | 21 | # Load the current module 22 | Import-Module “$scriptDir\BloxOne-DDI.psd1” 23 | 24 | # List all Public and Private functions 25 | <# 26 | $moduleObj = Get-Module BloxOne-DDI 27 | $allFunctions = $moduleObj.Invoke({Get-Command -Module BloxOne-DDI}) 28 | $pubFunctions = Get-Command -Module BloxOne-DDI 29 | Write-Verbose "Private Functions" 30 | Compare-Object -ReferenceObject $allFunctions -DifferenceObject $pubFunctions | Select-Object -ExpandProperty InputObject 31 | Write-Verbose "Public Functions" 32 | $pubFunctions 33 | #> 34 | -------------------------------------------------------------------------------- /BloxOne/Tests/010-Get-ConfigInfo.Tests.ps1: -------------------------------------------------------------------------------- 1 | # Requires -Version 7 2 | ### Sample PowerShell Script for BloxOne DDI 3 | ### Author: Don Smith 4 | ### Author-Email: dsmith@infoblox.com 5 | ### Version: 2020-08-03 Initial release 6 | 7 | #$DebugPreference = 'continue' 8 | #$VerbosePreference = 'SilentlyContinue' 9 | 10 | 11 | Write-Output @" 12 | ************************ 13 | >>> Beginning test : Get-ConfigInfo <<< 14 | ************************ 15 | "@ 16 | 17 | 18 | <# 19 | Test #1: Execute the commond without providing a file path 20 | Expected Results: 21 | - bloxone.ini in the current directory will be read 22 | - bloxone.ini has a [Private] section with a path to private.ini in the current directory 23 | - private.ini will also be read 24 | - results from private.ini will be used 25 | #> 26 | # Read the INI file for the base configuration 27 | Write-Output "Test #1: Attempting to read the default INI file (bloxone.ini)" 28 | $iniConfig = Get-ConfigInfo -DoNotCreate -Verbose 29 | if (Test-Path "bloxone.ini") { 30 | $iniConfig2 = Get-ConfigInfo "bloxone.ini" -DoNotCreate 31 | $iniConfig2 | Write-Output 32 | } else { 33 | Write-Warning "Expected file 'bloxone.ini' does not exist" 34 | } 35 | 36 | <# 37 | Test #2: Execute the commond providing a random filename 38 | Expected Results: 39 | - the filename will not exist so it will be automatically created 40 | - the contents of the file will have all of the necessary key/value pairs 41 | - the values will be defaults except for the API key 42 | #> 43 | # Read a random INI file 44 | Write-Output "Test #2: Create a random INI file template, create it if it does not exist" 45 | $randomFile = [System.IO.Path]::GetRandomFileName() 46 | Write-Output "Attempting to read the INI file $randomFile" 47 | $iniConfig2 = Get-ConfigInfo $randomFile 48 | # The file should have been created 49 | if (Test-Path $randomFile) { 50 | Write-Output "Contents of $randomFile" 51 | Get-Content $randomFile | Write-Output 52 | Remove-Item -Path $randomFile 53 | } else { 54 | # Error condition 55 | Write-Warning "Random file $randomFile was not created" 56 | } 57 | 58 | <# 59 | Test #3: Execute the commond providing a random filename 60 | Expected Results: 61 | - the filename will not exist and will not be created 62 | #> 63 | # Read a random INI file 64 | Write-OutPut "Test #3: Test a random file but do not create it" 65 | $randomFile = [System.IO.Path]::GetRandomFileName() 66 | Write-Output "Attempting to read the INI file $randomFile" 67 | $iniConfig2 = Get-ConfigInfo $randomFile -DoNotCreate 68 | # The file should NOT have been created 69 | if (Test-Path $randomFile) { 70 | # Error condition 71 | Write-Warning "Random file $randomFile was created. Contents of $randomFile" 72 | Get-Content $randomFile | Write-Output 73 | Remove-Item -Path $randomFile 74 | } else { 75 | Write-Output "Random file $randomFile was not created" 76 | } 77 | 78 | <# 79 | Test 4: Pass the filename via the pipeline 80 | Expected Results: 81 | - the filename is read and the results are determined similar to other tests 82 | #> 83 | Write-OutPut "Test #4: Accept the filename from the pipeline" 84 | $randomFile = [System.IO.Path]::GetRandomFileName() 85 | $iniConfig2 = $randomFile | Get-ConfigInfo -DoNotCreate 86 | # The file should NOT have been created 87 | if (Test-Path $randomFile) { 88 | # Error condition 89 | Write-Warning "Random file $randomFile was created. Contents of $randomFile" 90 | Get-Content $randomFile | Write-Output 91 | Remove-Item -Path $randomFile 92 | } else { 93 | Write-Output "Random file $randomFile was not created" 94 | } 95 | 96 | 97 | Write-Output @" 98 | ************************ 99 | >>> Test Complete <<< 100 | ************************ 101 | "@ 102 | -------------------------------------------------------------------------------- /BloxOne/Tests/020-Get-BaseUrl.Tests.ps1: -------------------------------------------------------------------------------- 1 | # Requires -Version 7 2 | ### Sample PowerShell Script for BloxOne DDI 3 | ### Author: Don Smith 4 | ### Author-Email: dsmith@infoblox.com 5 | ### Version: 2020-08-03 Initial release 6 | 7 | #$DebugPreference = 'continue' 8 | #$VerbosePreference = 'SilentlyContinue' 9 | 10 | 11 | Write-Output @" 12 | ************************ 13 | >>> Beginning test : Get-BaseUrl <<< 14 | ************************ 15 | "@ 16 | 17 | <# 18 | Test #1: Pass only the cspApp value 19 | Expected Results: 20 | - generate a valid CSP URL using defaults and the provided app 21 | #> 22 | Write-Output "Test #1: Pass only cspApp and generate a valid CSP URL" 23 | $myUrl = Get-BaseUrl -cspApp "ddi" 24 | if ($myUrl -eq "https://csp.infoblox.com/api/ddi/v1") { 25 | Write-Output "Passed with correct construction of Url" 26 | } else { 27 | Write-Warning "Wrong Url value created: $myUrl" 28 | } 29 | 30 | 31 | <# 32 | Test #2: Override the url default 33 | Expected Results: 34 | - generate a valid CSP URL 35 | #> 36 | Write-OutPut "Test #2: Define a custom URL" 37 | $myUrl = Get-BaseUrl "https://test3.csp.infoblox.com" "ddi" 38 | if ($myUrl -eq "https://test3.csp.infoblox.com/api/ddi/v1") { 39 | Write-Output "Passed with correct construction of Url" 40 | } else { 41 | Write-Warning "Wrong Url value created: $myUrl" 42 | } 43 | 44 | Write-Output @" 45 | ************************ 46 | >>> Test Complete <<< 47 | ************************ 48 | "@ 49 | -------------------------------------------------------------------------------- /BloxOne/Tests/025-Get-DDIUrls.Tests.ps1: -------------------------------------------------------------------------------- 1 | # Requires -Version 7 2 | ### Sample PowerShell Script for BloxOne DDI 3 | ### Author: Don Smith 4 | ### Author-Email: dsmith@infoblox.com 5 | ### Version: 2020-08-04 Initial release 6 | 7 | #$DebugPreference = 'continue' 8 | #$VerbosePreference = 'SilentlyContinue' 9 | 10 | 11 | 12 | Write-Output @" 13 | ************************ 14 | >>> Beginning test : Get-DDIUrls <<< 15 | ************************ 16 | "@ 17 | 18 | <# 19 | Test #1: Execute function only to use defaults 20 | Expected Results: 21 | - hashtable with mutliple valid URLs 22 | #> 23 | Write-Output "Test #1: Do not pass any values (accept defaults)" 24 | [hashtable]$myUrls = Get-DDIUrls 25 | if ($myUrls.Count -eq 3) { 26 | Write-Output "Success:: $($myurls.Count) items returned." 27 | } else { 28 | Write-Warning "Failure:: $($myurls.Count) items returned. Expected 3" 29 | } 30 | Write-Verbose $myUrls 31 | 32 | <# 33 | Test #2: Override the default values for cspHostname and apiVersion 34 | Expected Results: 35 | - generate a valid CSP URL with the modified values 36 | #> 37 | Write-Output "Test #2: Positionally pass modified values for cspHostname and apiVersion" 38 | [hashtable]$myUrls = Get-DDIUrls "https://modified.csp.infoblox.com" "v99" 39 | if ($myUrls.Count -eq 3) { 40 | Write-Output "Success:: $($myurls.Count) items returned." 41 | } else { 42 | Write-Warning "Failure:: $($myurls.Count) items returned. Expected 3" 43 | } 44 | # Test one result 45 | $expectedResult = "https://modified.csp.infoblox.com/api/ddi/v99" 46 | if ($myUrls.ipamUrl -eq $expectedResult) { 47 | Write-Output "Success:: cspHostname and apiVersion successfully modified" 48 | } else { 49 | Write-Warning "Failure:: modified ipamUrl not returned" 50 | Write-Output $myUrls 51 | } 52 | 53 | <# 54 | Test #3: Pass the INI config and section to get the desired values 55 | Expected Results: 56 | - generate a valid CSP URL with the specific settings from a section in the INI data 57 | #> 58 | Write-Output "Test #3: Pass the iniConfig and iniSection" 59 | [hashtable]$myUrls = Get-DDIUrls -iniConfig (Get-ConfigInfo) -iniSection "BloxOne" 60 | if ($myUrls.Count -eq 3) { 61 | Write-Output "Success:: $($myurls.Count) items returned." 62 | } else { 63 | Write-Warning "Failure:: $($myurls.Count) items returned. Expected 3" 64 | } 65 | Write-Verbose $myUrls 66 | # Save this value for the next test 67 | $myBloxOneIpamUrl = $myUrls.ipamUrl 68 | 69 | <# 70 | Test #4: Pass the INI config and section to get the desired values, Override the apiVersion 71 | Expected Results: 72 | - generate a valid CSP URL with the specific settings from a section in the INI data 73 | #> 74 | Write-Output "Test #4: Pass the iniConfig and iniSection and apiVersion" 75 | [hashtable]$myUrls4 = Get-DDIUrls -apiVersion "v99" -iniConfig (Get-ConfigInfo) -iniSection "BloxOne" 76 | $myBloxOneModifiedIpamUrl = $myUrls4.ipamUrl 77 | 78 | $mySplitMod = @($myBloxOneModifiedIpamUrl -split "/") 79 | $mySplitOrg = @($myBloxOneIpamUrl -split "/") 80 | 81 | # Make sure we have the same number of elements 82 | if ($mySplitMod.Count -eq $mySplitOrg.Count) { 83 | # We are on the right track 84 | $elementCount = $mySplitMod.Count 85 | # Only the last element should be different 86 | for ($i=0; $i -lt $elementCount-1; $i++) { 87 | if ($mySplitMod[$i] -eq $mySplitOrg[$i]) { 88 | # We are on the right track 89 | Write-Verbose "Success:: Match at $i, value $($mySplitMod[$i])" 90 | } else { 91 | Write-Warning "Failure:: element $i does not match ($($mySplitMod[$i]) vs $($mySplitOrg[$i]))" 92 | } 93 | } 94 | # Manually check the last element because it SHOULD be different 95 | if ($mySplitMod[-1] -ne $mySplitOrg[-1]) { 96 | Write-Output "Success:: Found desired difference ($($mySplitMod[$i]) vs $($mySplitOrg[$i]))" 97 | } else { 98 | Write-Warning "Failure:: Desired difference not found ($($mySplitMod[$i]) vs $($mySplitOrg[$i]))" 99 | } 100 | } else { 101 | Write-Warning "Failure:: Wrong # of elements returned ($mySplitMod.Count vs $mySplitOrg.Count)" 102 | } 103 | 104 | 105 | Write-Output @" 106 | ************************ 107 | >>> Test Complete <<< 108 | ************************ 109 | "@ 110 | -------------------------------------------------------------------------------- /BloxOne/Tests/100-List-DhcpServer.ps1: -------------------------------------------------------------------------------- 1 | # Requires -Version 7 2 | ### Sample PowerShell Script for BloxOne DDI 3 | ### Author: Don Smith 4 | ### Author-Email: dsmith@infoblox.com 5 | ### Version: 2020-08-04 Initial release 6 | 7 | #$DebugPreference = 'continue' 8 | #$VerbosePreference = 'continue' 9 | 10 | 11 | Write-Output @" 12 | ************************ 13 | >>> Beginning test : List-DhcpServer <<< 14 | ************************ 15 | "@ 16 | 17 | Write-Output "Prep configuration for subsequent tests..." 18 | 19 | # Get a valid config to work with 20 | $iniConfig = Get-ConfigInfo -DoNotCreate 21 | 22 | # Get all of the necessary URLs using the correct config info 23 | [hashtable]$h = Get-DDIUrls -iniSection "AMS" -iniConfig $iniConfig 24 | Write-Output $h 25 | 26 | # Build the Authorization header using the appropriate API Key from the config 27 | $headers = @{ 28 | "Authorization" = "Token " + $iniConfig.AMS.api_key 29 | } 30 | Write-Verbose "Authorization header = $($headers.Authorization)" 31 | 32 | # Get a list of all DHCP Servers 33 | # Start with constructing the URL 34 | $dhcpServersUrl = $h.ipamUrl + "/dhcp/server” 35 | Write-Output "Url to pull the list of servers: $dhcpServersUrl" 36 | 37 | # Get the object(s) 38 | $serverList = Invoke-RestMethod -Method ‘Get’ -Uri $dhcpServersUrl -Headers $headers 39 | Write-Output "$($serverList.results.Length) results returned" 40 | 41 | # Loop through the objects and display the name 42 | for ($i=0; $i -lt $serverList.results.Length; $i++) { 43 | Write-Verbose "#$i $($serverList.results[$i].name)" 44 | } 45 | 46 | 47 | Write-Output @" 48 | ************************ 49 | >>> Test Complete <<< 50 | ************************ 51 | "@ 52 | -------------------------------------------------------------------------------- /BloxOne/Tests/bloxone.ini: -------------------------------------------------------------------------------- 1 | # INI Sample File 2 | # 3 | # Consider a configuration file to read basic info from 4 | # This is INI format to match Chris Marrison’s setup 5 | # Might consider doing this is JSON 6 | # Filename could be passed and/or section to read could be passed 7 | # Do not quote the values 8 | # 9 | [AMS] 10 | url = https://csp.infoblox.com 11 | api_version = v1 12 | api_key = 13 | 14 | [Private] 15 | # path to private INI file with real API keys 16 | # reserved heading 17 | path = private.ini 18 | 19 | [BloxOne] 20 | url = https://bloxone.csp.infoblox.com 21 | api_key = 22 | api_version = v1 23 | -------------------------------------------------------------------------------- /Infoblox-DDI/Infoblox-DDI.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'Infoblox-DDI' 3 | # 4 | # Generated by: Don Smith 5 | # Generated on: 2016-Sep-26 6 | # 7 | 8 | @{ 9 | 10 | # Script module or binary module file associated with this manifest 11 | RootModule = 'Infoblox-DDI.psm1' 12 | 13 | # Version number of this module. 14 | ModuleVersion = '0.3.1' 15 | 16 | # ID used to uniquely identify this module 17 | # GUID = '' 18 | 19 | # Author of this module 20 | Author = 'Don Smith' 21 | 22 | # Company or vendor of this module 23 | # CompanyName = '' 24 | 25 | # Copyright statement for this module 26 | Copyright = '(c) 2016 Don Smith. All rights reserved.' 27 | 28 | # Description of the functionality provided by this module 29 | # Description = '' 30 | 31 | # Minimum version of the Windows PowerShell engine required by this module 32 | PowerShellVersion = '5.0' 33 | 34 | # Name of the Windows PowerShell host required by this module 35 | # PowerShellHostName = '' 36 | 37 | # Minimum version of the Windows PowerShell host required by this module 38 | # PowerShellHostVersion = '' 39 | 40 | # Minimum version of the .NET Framework required by this module 41 | # DotNetFrameworkVersion = '' 42 | 43 | # Minimum version of the common language runtime (CLR) required by this module 44 | # CLRVersion = '' 45 | 46 | # Processor architecture (None, X86, Amd64) required by this module 47 | # ProcessorArchitecture = '' 48 | 49 | # Modules that must be imported into the global environment prior to importing this module 50 | # RequiredModules = @() 51 | 52 | # Assemblies that must be loaded prior to importing this module 53 | # RequiredAssemblies = @() 54 | 55 | # Script files (.ps1) that are run in the caller's environment prior to importing this module 56 | # ScriptsToProcess = @() 57 | 58 | # Type files (.ps1xml) to be loaded when importing this module 59 | # TypesToProcess = @() 60 | 61 | # Format files (.ps1xml) to be loaded when importing this module 62 | # FormatsToProcess = @() 63 | 64 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 65 | # NestedModules = @() 66 | 67 | # Functions to export from this module 68 | FunctionsToExport = '*' 69 | 70 | # Cmdlets to export from this module 71 | CmdletsToExport = '*' 72 | 73 | # Variables to export from this module 74 | VariablesToExport = '*' 75 | 76 | # Aliases to export from this module 77 | AliasesToExport = '*' 78 | 79 | # List of all modules packaged with this module 80 | # ModuleList = @() 81 | 82 | # List of all files packaged with this module 83 | # FileList = @() 84 | 85 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 86 | PrivateData = @{ 87 | 88 | PSData = @{ 89 | 90 | # Tags applied to this module. These help with module discovery in online galleries. 91 | Tags = 'Infoblox','IPAM' 92 | 93 | # A URL to the license for this module. 94 | LicenseUri = 'https://github.com/Ameritus/PowerShell-Test/LICENSE' 95 | 96 | # A URL to the main website for this project. 97 | ProjectUri = 'https://github.com/Ameritus/PowerShell-Test' 98 | 99 | # A URL to an icon representing this module. 100 | # IconUri = '' 101 | 102 | # ReleaseNotes of this module 103 | ReleaseNotes = 'Nothing here.' 104 | 105 | } # End of PSData hashtable 106 | 107 | } # End of PrivateData hashtable 108 | 109 | # HelpInfo URI of this module 110 | # HelpInfoURI = '' 111 | 112 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 113 | DefaultCommandPrefix = 'IB' 114 | 115 | } 116 | -------------------------------------------------------------------------------- /Infoblox-DDI/Infoblox-DDI.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 5.0 2 | 3 | # Get public and private function definition files. 4 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) 5 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) 6 | 7 | # Dot source the files 8 | Foreach($import in @($Public + $Private)) 9 | { 10 | Try 11 | { 12 | . $import.fullname 13 | } 14 | Catch 15 | { 16 | Write-Error -Message "Failed to import function $($import.fullname): $_" 17 | } 18 | } 19 | 20 | # Export everything in the public folder 21 | Export-ModuleMember -Function $Public.Basename 22 | -------------------------------------------------------------------------------- /Infoblox-DDI/Infoblox-Get-Request-Format.txt: -------------------------------------------------------------------------------- 1 | Arguments 2 | 3 | There can be no arguments to objtype or it can have one or multiple conditions in the following format: 4 | 5 | { field | * attribute [ ] } [ modifiers ] = value 6 | 7 | Where: 8 | 9 | field is a documented field of the object. 10 | 11 | attribute is the name of an extensible attribute. Must be prefixed by an asterisk (*) and optionally followed by a single space. 12 | 13 | modifiers is optional and can be one or more search modifiers supported by the field or extensible attribute value type. 14 | 15 | value is the value or regular expression to search for. 16 | 17 | When combining multiple conditions, all must be satisified in order to match an object (i.e. conditions are combined with AND). 18 | 19 | When a field is a list or an extensible attribute that can have multiple values, the condition is true if any value in the list matches. 20 | 21 | If no modifiers are used, it is an exact match. 22 | 23 | Search Modifiers 24 | 25 | A search argument can use the following modifiers: 26 | 27 | Modifier Functionality 28 | ! Negates the condition. 29 | : Makes string matching case insensitive. 30 | ~ Regular expression search. Expressions are unanchored. 31 | < Less than or equal. 32 | > Greater than or equal. 33 | Only one of the following can be specified at one time: greater than, less than, and regular expressions. 34 | 35 | You can find the modifiers that are supported by each field in the respective documentation. Unsupported combinations will result in an error. 36 | 37 | Depending on the attribute type, following are modifiers supported by extensible attributes: 38 | 39 | integer and date support !, < and >. All other types behave like strings and support !, ~ and :. -------------------------------------------------------------------------------- /Infoblox-DDI/Notes/examples.txt: -------------------------------------------------------------------------------- 1 | curl -k1 -u admin:infoblox -X GET https://172.16.98.15/wapi/v2.1/netork?network_view=external 2 | 3 | curl -k1 -u admin:infoblox -X GET https://172.16.98.15/wapi/v2.1/network?member=dhcpmember,172.16.98.15 4 | 5 | curl -k1 -u admin:infoblox -X GET https://172.16.98.15/wapi/v2.1/network?member=dhcpmember,172.16.98.15&*Site~=a 6 | 7 | regex is really a "contains" option 8 | ipv4addr is likely not needed since it seems to work identically to network 9 | 10 | 11 | network_view = exact text 12 | 13 | comment = exact text 14 | comment := case insensitive text (exact string) 15 | comment ~= regex (partial string matching / not full regex) 16 | comment ~:= case insensitive / regex 17 | 18 | ipv4addr = exact IP 19 | ipv4addr ~= regex 20 | 21 | network = exact IP/mask 22 | network ~= regex 23 | 24 | network_container = exact IP/mask 25 | 26 | unmanaged = 0 (no) or 1 (yes) 27 | 28 | contains_address = exact IP 29 | (only works with network_view, all others ignored) 30 | 31 | member = dhcpmember,ipv4address[,name] 32 | member = ipv6dhcpmember,ipv6address[,name] 33 | member = msdhcpserver,ipv4address 34 | 35 | *EA_NAME = case sensitive match 36 | *EA_NAME := case insensitive match 37 | *EA_NAME ~= case sensitive match / contains 38 | *EA_NAME ~:= case insensitive match / contains 39 | 40 | -------------------------------------------------------------------------------- /Infoblox-DDI/Private/ConvertFrom-JSON.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Uses the JavaScript serializer object. 4 | #> 5 | function script:ConvertFrom-JSON { 6 | Param ( 7 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 8 | $json 9 | ) 10 | 11 | BEGIN { 12 | Write-Verbose '[convert-from-json] Begin' 13 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 14 | $data_array = @() 15 | } 16 | 17 | PROCESS { 18 | $data = $ser.DeSerializeObject($json) 19 | $data_array += $data 20 | } 21 | 22 | END { 23 | return $data_array 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Infoblox-DDI/Private/ConvertTo-JSON.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Uses the JavaScript serializer object. The built-in PS ConvertTo-Json script is broken for nested extattr information. 4 | #> 5 | function script:ConvertTo-JSON { 6 | Param ( 7 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 8 | $data 9 | ) 10 | 11 | BEGIN { 12 | Write-Verbose '[convert-to-json] Begin' 13 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 14 | $data_array = @() 15 | } 16 | 17 | PROCESS { 18 | $json = $ser.Serialize($data) 19 | $data_array += $json 20 | } 21 | 22 | END { 23 | return $data_array 24 | } 25 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Private/ConvertTo-URIEncodedFormat.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Encodes the search URI 4 | .Description 5 | Specific characters must be replaced with hex values or WAPI (or PowerShell) may choke. 6 | .Parameter uri_string 7 | A string in WAPI URI compatible format. 8 | .Outputs 9 | Encoded version of the string 10 | .Example 11 | ConvertTo-URIEncodedFormat $my_searchString 12 | #> 13 | function script:ConvertTo-URIEncodedFormat { 14 | Param ( 15 | [Parameter(Mandatory=$true,Position=0)] 16 | [string]$uri_string 17 | ) 18 | BEGIN { 19 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] Begin" 20 | } 21 | PROCESS { 22 | # Make a copy of the string 23 | $uri = $uri_string 24 | # Replace the with a "%20" 25 | $uri = $uri -replace ' ', "%20" 26 | # Replace the with a "%21" 27 | $uri = $uri -replace '!', "%21" 28 | # Replace the with a "%2A" 29 | #$uri = $uri -replace '*', "%2A" 30 | # Replace the with a "%2B" 31 | $uri = $uri -replace '\+', "%2B" 32 | 33 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] Original: '$uri_string'" 34 | Write-Debug "[DEBUG:ConvertTo-URIEncodedFormat] New : '$uri'" 35 | } 36 | END { 37 | return $uri 38 | } 39 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Private/Find-Object.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Search for an Infoblox object and return a list of results 4 | 5 | .Description 6 | Request an object type and search string to find matching objects in the Grid. 7 | Results are always returned as an array. 8 | 9 | .Parameter search_string 10 | A string in URI compatible format 11 | 12 | .Parameter objtype 13 | A valid Infoblox object type (for example: 'network' or 'record:host') 14 | 15 | .Outputs 16 | An array of results 17 | 18 | .Example 19 | Find-Object 192.168.1.0 network 20 | Find-Object -search_string 192.168.1.0 -objtype network 21 | 22 | Find a network that matches the address 192.168.1.0 23 | 24 | .Example 25 | Find-Object 192.168 network 26 | 27 | Find all networks that contain 192.168 in the address 28 | 29 | .Example 30 | Find-Object 31 | 32 | Prompt for the search string and object type 33 | 34 | #> 35 | 36 | function script:Find-Object { 37 | Param ( 38 | [Parameter(Mandatory=$false,Position=0)] 39 | [string]$search_string = $( Read-Host -Prompt "Enter a valid search string" ), 40 | [Parameter(Mandatory=$false,Position=1)] 41 | [string]$objtype = $( Read-Host -Prompt "Enter a valid object type" ) 42 | ) 43 | 44 | BEGIN { 45 | Write-Debug "[DEBUG:Find-Object] Begin" 46 | 47 | # Make sure we already have a session established 48 | if (!$script:ib_session) { 49 | Write-Error "[ERROR:Find-Object] Try creating a session first using 'Connect-GridMaster'" 50 | return $false 51 | } 52 | } 53 | 54 | PROCESS { 55 | } 56 | 57 | END { 58 | Write-Verbose "[Find-Object] $objtype : $search_string" 59 | 60 | # Build the URI filter/search string 61 | if ($search_string) { $uri_filter = "search_string~=$search_string" } 62 | if ($objtype) { $uri_filter = "$uri_filter" + '&' + "objtype=$objtype" } 63 | 64 | # Assemble the URI search string 65 | $uri = $script:ib_uri_base + "search" + '?' + "$uri_filter" 66 | 67 | # Append the max results we want returned 68 | if ($script:ib_max_results) { $uri = "$uri" + '&' + "_max_results=$script:ib_max_results" } 69 | 70 | # Debug the URI 71 | Write-Debug "[DEBUG:Find-Object] URI '$uri'" 72 | 73 | # Send the request and print any error messages 74 | try { 75 | $results = Invoke-RestMethod -Uri $uri -Method Get -WebSession $script:ib_session 76 | } catch { 77 | Write-Error "[ERROR:Find-Object] There was an error performing the search." 78 | # $_.ErrorDetails is absolutely useless here 79 | #Write-Host $_.ErrorDetails 80 | 81 | # Get the actual message provided by Infoblox 82 | $result = $_.Exception.Response.GetResponseStream() 83 | $reader = New-Object System.IO.StreamReader($result) 84 | $reader.BaseStream.Position = 0 85 | $reader.DiscardBufferedData() 86 | $responseBody = $reader.ReadToEnd() 87 | Write-Error [ERROR:Find-Object] $responseBody 88 | 89 | return $false 90 | } 91 | 92 | return $results 93 | } 94 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Private/Get-Object.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Get an Infoblox object based on the reference passed. 4 | 5 | .Description 6 | Get the referenced object and any additional columns requested. 7 | 8 | .Parameter _ref 9 | The object reference obtained from a 'find' operation 10 | 11 | .Parameter _return_fields 12 | Additional columns to retrieve aside from those returned by default 13 | 14 | .Outputs 15 | An object array of name/value pairs 16 | 17 | .Example 18 | Get-Object 192.168.1.0 network 19 | 20 | Find a network that matches the address 192.168.1.0 21 | 22 | #> 23 | 24 | function script:Get-Object { 25 | Param ( 26 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] 27 | [string]$_ref, 28 | [Parameter(Mandatory=$false,Position=1)] 29 | [string]$_return_fields 30 | ) 31 | 32 | BEGIN { 33 | Write-Debug '[DEBUG:Get-Object] Begin' 34 | 35 | if (!$script:ib_session) { 36 | Write-Error "[ERROR:Get-Object] Try creating a session first. 'Connect-GridMaster'" 37 | return $false 38 | } 39 | 40 | # Initialize our counter and hashtable 41 | [hashtable[]]$data_array = $null 42 | } 43 | 44 | PROCESS { 45 | Write-Verbose "[Get-Object] [$_ref] [$_return_fields]" 46 | Write-Debug "[DEBUG:Get-Object] _ref = $_ref" 47 | Write-Debug "[DEBUG:Get-Object] _return_fields = $_return_fields" 48 | 49 | # Set up the URI 50 | $uri_return_type = "_return_type=json-pretty" 51 | $uri = $script:ib_uri_base + "$_ref" + '?' + $uri_return_type 52 | 53 | # Add the requested return fields to the URI 54 | if ($_return_fields) { 55 | # Replace '+' with '%2b' 56 | $uri = "$uri" + '&' + "_return_fields%2b=$_return_fields" 57 | } 58 | 59 | # Set the limit for the maximum results to return 60 | if ($script:ib_max_results) { $uri = "$uri" + '&' + "_max_results=$script:ib_max_results" } 61 | 62 | # Debug the URI 63 | Write-Debug "[DEBUG:Get-Object] URI '$uri'" 64 | 65 | # Try to obtain the data and print an error message if there is one 66 | try { 67 | $local_results = Invoke-WebRequest -Uri $uri -Method Get -WebSession $script:ib_session 68 | } catch { 69 | Write-Error "[ERROR:Get-Object] There was an error getting the data." 70 | Write-Error "[ERROR:Get-Object] URI '$uri'" 71 | # $_.ErrorDetails is absolutely useless here 72 | #Write-Host $_.ErrorDetails 73 | 74 | # Get the actual message provided by Infoblox 75 | $result = $_.Exception.Response.GetResponseStream() 76 | $reader = New-Object System.IO.StreamReader($result) 77 | $reader.BaseStream.Position = 0 78 | $reader.DiscardBufferedData() 79 | $responseBody = $reader.ReadToEnd() 80 | Write-Error [ERROR:Get-Object] $responseBody 81 | 82 | } 83 | 84 | # Grab only the content portion of the returned object 85 | $obj_content = $local_results.Content 86 | 87 | # Deserialize the JSON data into something manageable 88 | $data = $obj_content | IB-ConvertFrom-JSON 89 | 90 | # Debug the raw data 91 | Write-Debug "[DEBUG:Get-Object] Got data '$data'" 92 | 93 | # Append the raw data into an array (for pipeline requests) 94 | $data_array += $data 95 | Write-Debug "[DEBUG:Get-Object] Array '$data_array'" 96 | } 97 | 98 | END { 99 | Write-Debug "[DEBUG:Get-Object] Returning data array" 100 | return $data_array 101 | } 102 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Private/IB-ConvertFrom-JSON.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Uses the JavaScript serializer object. 4 | #> 5 | function script:IB-ConvertFrom-JSON { 6 | Param ( 7 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 8 | $json 9 | ) 10 | 11 | BEGIN { 12 | Write-Debug '[DEBUG:IB-ConvertFrom-JSON] Begin' 13 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 14 | $data_array = @() 15 | } 16 | 17 | PROCESS { 18 | $data = $ser.DeSerializeObject($json) 19 | $data_array += $data 20 | } 21 | 22 | END { 23 | return $data_array 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Infoblox-DDI/Private/IB-ConvertTo-JSON.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Uses the JavaScript serializer object. The built-in PS ConvertTo-Json script is broken for nested extattr information. 4 | #> 5 | function script:IB-ConvertTo-JSON { 6 | Param ( 7 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 8 | $data 9 | ) 10 | 11 | BEGIN { 12 | Write-Debug '[DEBUG:IB-ConvertTo-JSON] Begin' 13 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 14 | $data_array = @() 15 | } 16 | 17 | PROCESS { 18 | $json = $ser.Serialize($data) 19 | $data_array += $json 20 | } 21 | 22 | END { 23 | return $data_array 24 | } 25 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Private/Set-IgnoreSelfSignedCerts.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Configures PowerShell to ignore self-signed certificates 4 | 5 | .DESCRIPTION 6 | Infoblox uses self-signed certificates by default. 7 | This function overrides the PowerShell default setting so a successful connection can be established. 8 | 9 | .EXAMPLE 10 | Set-IgnoreSelfSignedCerts 11 | 12 | .NOTES 13 | This should be the first command run (before attempting to create a session) unless you have uploaded signed certificates to the Infoblox Grid Master. 14 | 15 | #> 16 | function script:Set-IgnoreSelfSignedCerts { 17 | ######################################## 18 | # Do the following to ignore self-signed certificates 19 | add-type @" 20 | using System.Net; 21 | using System.Security.Cryptography.X509Certificates; 22 | public class TrustAllCertsPolicy : ICertificatePolicy { 23 | public bool CheckValidationResult( 24 | ServicePoint srvPoint, X509Certificate certificate, 25 | WebRequest request, int certificateProblem) { 26 | return true; 27 | } 28 | } 29 | "@ 30 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 31 | } 32 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Add-ExtensibleAttribute.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Sets the value of an EA to the value passed 4 | 5 | .Description 6 | Used to set the value for an EA 7 | 8 | .Parameter name 9 | The name of the extensible attribute (EA) to set a value for 10 | 11 | .Parameter value 12 | The value of the extensible attribute 13 | 14 | .Outputs 15 | Hash object with the EA set to the appropriate value 16 | 17 | .Example 18 | # Sets the State to VA 19 | Set-ExtensibleAttribute "State" "VA" 20 | #> 21 | 22 | function script:Set-ExtensibleAttribute { 23 | Param ( 24 | [Parameter(Mandatory=$true,Position=0)] 25 | [string]$name, 26 | [Parameter(Mandatory=$true,Position=1)] 27 | [string]$value 28 | ) 29 | 30 | BEGIN { 31 | Write-Debug "[DEBUG:Set-ExtensibleAttribute] Begin" 32 | $eaHash = @{} 33 | } 34 | 35 | PROCESS { 36 | # Define a hash for the current pair of objects 37 | $myEA = @{} 38 | 39 | #### Does not currently handle a multi-value EA 40 | # Add the value to the 'value' key 41 | $myEA.Add("value", $value) 42 | 43 | # Now add the key ('name') and add the value object 44 | $eaHash.Add($name, $myEA) 45 | } 46 | 47 | END { 48 | Write-Debug "[DEBUG:Set-ExtensibleAttribute] End" 49 | return $eaHash 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Connect-GridMaster.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Establishes a session to an Infoblox Grid Master for all subsequent data calls. 4 | 5 | .DESCRIPTION 6 | Creates a connection to an Infoblox Grid Master and leaves open an active session. Defines several global variables for subsequent use. 7 | 8 | ib_grid_name The name of the Grid (for multi Grid environments -- like Test/Dev vs. Production) 9 | ib_grid_master The IP or hostname of the Grid we are connecting to 10 | ib_grid_ref A reference to the Grid object 11 | ib_session The WebSession variable 12 | ib_uri_base "https://$grid_master/wapi/$wapi_ver" 13 | ib_username The admin name 14 | ib_wapi_ver The WAPI version string used to connect 15 | 16 | .PARAMETER grid_master 17 | A single computer name or IP address. 18 | 19 | .PARAMETER username 20 | Authenticating user; defaults to "admin" 21 | 22 | .PARAMETER password 23 | Admin password. If not entered, use the -ask_pw option. 24 | 25 | .PARAMETER wapi_ver 26 | Use to specify the exact version of the WAPI to use. 27 | The version must be in "v#.#" format and must be supported by the installed version of NIOS. 28 | Defaults to "v1.3" 29 | 30 | .PARAMETER max_results 31 | Determines the maximum number of results to be returned. 32 | Enter as a whole number ("10000"). 33 | Defaults to 10,000. 34 | 35 | .Parameter force 36 | Forces a connection where self-signed certificates are used 37 | 38 | .PARAMETER ask_pw 39 | Forces a prompt for inputting the password manually so it does not have to be entered in clear text on the command line. 40 | 41 | .OUTPUTS 42 | Optional connection message (Grid name you are connected to) 43 | TRUE or FALSE depending on the connection status 44 | 45 | .EXAMPLE 46 | IB-Create-Session 192.168.1.2 admin infoblox 47 | Creates a connection to a Grid Master using default credentials and IP address. 48 | 49 | .EXAMPLE 50 | IB-Create-Session 192.168.1.2 admin -ask_pw 51 | Creates a connection but allows entering the password securely (via prompt with masking). 52 | 53 | .NOTES 54 | This should be the first command run to ensure that a connection is established and global variables are properly configured. 55 | 56 | #> 57 | 58 | function script:Connect-GridMaster { 59 | Param ( 60 | [Parameter(Mandatory=$false,Position=0)] 61 | [string]$grid_master = "192.168.1.2", 62 | [Parameter(Mandatory=$false,Position=1)] 63 | [string]$username = "admin", 64 | [Parameter(Mandatory=$false,Position=2)] 65 | [string]$password = "infoblox", 66 | [Parameter(Mandatory=$false,Position=3)] 67 | [string]$wapi_ver = "v1.3", 68 | [Parameter(Mandatory=$false,Position=4)] 69 | [int]$max_results = "1000", 70 | [Parameter(Mandatory=$false)] 71 | [switch]$force, 72 | [Parameter(Mandatory=$false)] 73 | [switch]$ask_pw 74 | ) 75 | 76 | BEGIN { 77 | Write-Debug "[DEBUG:Connect-GridMaster] Begin" 78 | 79 | # Reset all script variables to null until a successful connection is established 80 | $script:ib_grid_name = $null 81 | $script:ib_grid_master = $null 82 | $script:ib_grid_ref = $null 83 | $script:ib_max_results = $null 84 | $script:ib_session = $null 85 | $script:ib_uri_base = $null 86 | $script:ib_username = $null 87 | $script:ib_wapi_ver = $null 88 | } 89 | 90 | PROCESS { 91 | # There is nothing to loop through so we'll skip this 92 | } 93 | 94 | END { 95 | # Check to see if we are forcing a connection to a Grid with self-signed certificates 96 | if ($force) { 97 | Write-Debug "[DEBUG:Connect-GridMaster] Forcing connection" 98 | Set-IgnoreSelfSignedCerts 99 | } 100 | 101 | # Prompt for the password, if required and build the credentials 102 | if ($ask_pw) { 103 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 104 | Write-Host "" 105 | } else { 106 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 107 | } 108 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 109 | 110 | # Set the base URI for all WAPI requests 111 | $uri_base = "https://$grid_master/wapi/$wapi_ver/" 112 | Write-Debug "[DEBUG:Connect-GridMaster] URI base = $uri_base" 113 | 114 | # Set the URI to retrieve the Grid object 115 | $uri = $uri_base + "grid" 116 | 117 | # Make a connection to the Grid and print the detailed error message as necessary 118 | try { 119 | $grid_obj = Invoke-RestMethod -Uri $uri -Method Get -Credential $credential -SessionVariable new_session 120 | } catch { 121 | Write-Error '[ERROR:Connect-GridMaster] There was an error connecting to the Grid.' 122 | # $_.ErrorDetails is absolutely useless here 123 | #Write-Host $_.ErrorDetails 124 | 125 | # Get the actual message provided by Infoblox 126 | $result = $_.Exception.Response.GetResponseStream() 127 | $reader = New-Object System.IO.StreamReader($result) 128 | $reader.BaseStream.Position = 0 129 | $reader.DiscardBufferedData() 130 | $responseBody = $reader.ReadToEnd() 131 | Write-Error [ERROR:Connect-GridMaster] $responseBody 132 | 133 | return $false 134 | } 135 | 136 | # Get the name of the Grid 137 | $s1 = $grid_obj._ref.IndexOf(":") 138 | $grid_name = $grid_obj._ref.Substring( $( $s1 + 1 ) ) 139 | 140 | # Update global variables with new connection information 141 | $script:ib_grid_name = $grid_name 142 | $script:ib_grid_master = $grid_master 143 | $script:ib_grid_ref = $( $grid_obj._ref ) 144 | $script:ib_max_results = $max_results 145 | $script:ib_session = $new_session 146 | $script:ib_uri_base = $uri_base 147 | $script:ib_username = $username 148 | $script:ib_wapi_ver = $wapi_ver 149 | 150 | Write-Host "# Connected to Grid: '$grid_name'" 151 | 152 | # Update the schema version to the latest if we are still using v1.3 153 | if ($wapi_ver -eq "v1.3") { 154 | Set-IBWapiVersion 155 | } 156 | 157 | return $true 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Find-Network.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Search for an Infoblox network and return a list of results 4 | 5 | .Description 6 | Requires at least one parameter for the search to work. 7 | 8 | .Parameter search_string 9 | A string in WAPI URI compatible format. 10 | 11 | .Parameter return_fields 12 | A list of comma separated return fields to be included in the results. 13 | 14 | .Parameter comment 15 | The comment or initial part of the comment to search for 16 | 17 | .Parameter comment_match_type 18 | The operator to use for the comment search (defaults to '=' which is an exact match). 19 | Acceptable options are: (1) '=' for an exact match, (2) ':=' for exact case insensitive match, (3) '~=' for contains, and (4) '~:=' for case insensitive begins with. 20 | 21 | .Parameter network 22 | The network address to search for (no mask). 23 | Defaults to allow a 'begins with' search. 24 | 25 | .Parameter network_exact_match 26 | A switch that enables an exact match on the network address 27 | 28 | .Parameter network_view 29 | The name of the network view to filter results for. 30 | 31 | .Parameter contains_address 32 | Requires a valid IP address and will return the network the IP address belongs to. 33 | WAPI documentation says this is only compatible with network_view. 34 | 35 | .Parameter network_container 36 | Requires a network/mask (i.e. 172.16.0.0/16) and will return networks that are contained within this network container. 37 | 38 | .Parameter unmanaged 39 | Switch parameter that filters results to unmanaged networks only 40 | 41 | .Parameter ipv4member 42 | Requires a valid IPv4 address and will return networks assigned to this Infoblox Grid member. 43 | 44 | .Parameter ipv6member 45 | Requires a valid IPv6 address and will return networks assigned to this Infoblox Grid member. 46 | 47 | .Parameter msftmember 48 | Requires a valid IPv4 address and will return networks assigned to this Microsoft Grid member. 49 | 50 | .Outputs 51 | An array of results 52 | 53 | .Example 54 | Find-Network -return_fields "extattrs" -network 192.168 55 | 56 | Find all networks starting with '192.168'" and include the 'extattrs' field in the results 57 | 58 | .Example 59 | Find-Network -return_fields "extattrs" -network 192.168 -search_string "*Country=US" 60 | 61 | Find all networks starting with '192.168' where the Country is 'US'" and include the 'extattrs' field in the results 62 | 63 | .Example 64 | Find-Network -return_fields "extattrs" -comment test -comment_match_type ~:= -network_view external 65 | 66 | Find networks with 'test' in the comment (case insensitive) located in the 'external' network view and include the 'extattrs' field in the results 67 | #> 68 | 69 | 70 | function script:Find-Network { 71 | Param ( 72 | [Parameter(Mandatory=$false,Position=0)] 73 | [string]$search_string, 74 | [Parameter(Mandatory=$false,Position=1)] 75 | [string]$return_fields = $null, 76 | 77 | [Parameter(Mandatory=$false,Position=2)] 78 | [string]$comment, 79 | [Parameter(Mandatory=$false,Position=3)] 80 | [ValidateSet("=", "~=", ":=", "~:=")] 81 | [string]$comment_match_type, 82 | 83 | [Parameter(Mandatory=$false,Position=4)] 84 | [string]$network, 85 | [Parameter(Mandatory=$false,Position=5)] 86 | [switch]$network_exact_match, 87 | 88 | [Parameter(Mandatory=$false,Position=6)] 89 | [string]$network_view, 90 | 91 | [Parameter(Mandatory=$false,Position=7)] 92 | [string]$contains_address, 93 | 94 | [Parameter(Mandatory=$false,Position=8)] 95 | [string]$network_container, 96 | 97 | # Only from the following will actually work at any one time 98 | # Tried using ParameterSetName but got errors for some reason 99 | [Parameter(Mandatory=$false,Position=9)] 100 | [switch]$unmanaged, 101 | 102 | [Parameter(Mandatory=$false,Position=10)] 103 | [ValidatePattern("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")] 104 | [string]$ipv4member, 105 | 106 | [Parameter(Mandatory=$false,Position=11)] 107 | [ValidatePattern("(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}")] 108 | [string]$ipv6member, 109 | 110 | # Validate only IPv4 for now; may need to update this later 111 | [Parameter(Mandatory=$false,Position=12)] 112 | [ValidatePattern("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")] 113 | [string]$msftmember 114 | 115 | ) 116 | 117 | BEGIN { 118 | Write-Debug "[DEBUG:Find-Network] Begin" 119 | $my_Debug = $false 120 | 121 | ########## 122 | # Gather data for debugging and verbose output 123 | $myinvoc = $MyInvocation 124 | $my_functionName = $myinvoc.InvocationName 125 | 126 | ########## 127 | # Gather more data for debugging purposes (if necessary) 128 | if ($myinvoc.BoundParameters.Debug) { 129 | $my_functionLine = $myinvoc.Line.Trim() 130 | $my_functionParams = $my_functionLine -replace "$my_functionName ", "" 131 | $my_Debug = $true 132 | 133 | Write-Host "[DEBUG:Find-Network] Line : '$my_functionLine'" 134 | Write-Host "[DEBUG:Find-Network] Name : '$my_functionName'" 135 | Write-Host "[DEBUG:Find-Network] Params: '$my_functionParams'" 136 | 137 | #$incoming_parameters = $myinvoc.BoundParameters 138 | #foreach ($key in $incoming_parameters.GetEnumerator()) { $key.Key + "," + $key.Value } 139 | Write-Host "" 140 | } 141 | 142 | # Set up our search array 143 | $search_array = @() 144 | 145 | # Set up for determining if we have a valid search string 146 | $valid_search = $false 147 | 148 | # Check to make sure the $return_fields value is comma separated 149 | $fields_array = $return_fields.Split(",").Trim() 150 | $return_fields = $fields_array -join "," 151 | 152 | # Include the search string passed 153 | if (! [string]::IsNullorEmpty($search_string)) { 154 | $search_array += "$search_string" 155 | } 156 | 157 | # Process network handling; network contains the value to search, network_exact_match (=) 158 | if ($network) { 159 | $str1 = "network" 160 | if (! $network_exact_match) { 161 | $str1 += "~" 162 | } 163 | $str1 += "=$network" 164 | $search_array += $str1 165 | } 166 | 167 | # Process comment handling; comment contains the value to search, comment_match_type (=, ~=, :=, ~:=) 168 | if ($comment) { 169 | if ([string]::IsNullorEmpty($comment_match_type)) { 170 | $comment_match_type = "=" 171 | } 172 | $str1 = "comment" + $comment_match_type + $comment 173 | #$str1 = $str1 -replace " ", "%20" 174 | $search_array += $str1 175 | } 176 | 177 | # Set up network_view filtering 178 | if ($network_view) { 179 | $str1 = "network_view=$network_view" 180 | $search_array += $str1 181 | } 182 | 183 | # Set up contains_address filtering 184 | if ($contains_address) { 185 | $search_array += "contains_address=$contains_address" 186 | } 187 | 188 | # Set up network_container filtering 189 | if ($network_container) { 190 | $search_array += "network_container=$network_container" 191 | } 192 | 193 | # Set up unmanaged network filtering 194 | if ($unmanaged) { 195 | $search_array += "unmanaged=1" 196 | } 197 | 198 | # Process ipv4member, ipv6member, and msftmember 199 | if ($ipv4member) { 200 | $search_array += "member=dhcpmember,$ipv4member" 201 | } 202 | if ($ipv6member) { 203 | $search_array += "member=ipv6dhcpmember,$ipv6member" 204 | } 205 | if ($msftmember) { 206 | $search_array += "member=msdhcpserver,$msftmember" 207 | } 208 | 209 | Write-Debug "[DEBUG:Find-Network] search_array = '$search_array'" 210 | 211 | # If the array is not empty, we have valid criteria 212 | if ((! [string]::IsNullorEmpty($search_array)) -or (! [string]::IsNullorEmpty($search_string))) { 213 | $valid_search = $true 214 | } 215 | } 216 | 217 | PROCESS { 218 | Write-Debug "[DEBUG:Find-Network] Process" 219 | 220 | # Make sure we have something to do 221 | if (! $valid_search) { 222 | Write-Verbose "[DEBUG:Find-Network] No valid search criteria provided" 223 | return $false 224 | } 225 | 226 | # Build the URI base object filter 227 | $uri = $script:ib_uri_base + "network" + '?' 228 | 229 | # Process the array we just built 230 | if ($search_array.Count -gt 0) { 231 | # Add the return fields to the search string 232 | $combined_search = $search_array -join '&' 233 | Write-Debug "[DEBUG:Find-Network] combined_search = '$combined_search'" 234 | 235 | $uri += "$combined_search" 236 | } 237 | 238 | # Append any additional return fields requested 239 | $uri += "&_return_fields+=" + $return_fields 240 | 241 | # Append the max results we want returned 242 | if ($script:ib_max_results) { $uri += '&' + "_max_results=$script:ib_max_results" } 243 | 244 | # Debug the URI 245 | Write-Verbose "[DEBUG:Find-Network] URI '$uri'" 246 | 247 | # Fix up the URI since the WAPI and/or PowerShell chokes 248 | if ($my_Debug) { 249 | $uri = ConvertTo-URIEncodedFormat $uri -Debug 250 | } 251 | else { 252 | $uri = ConvertTo-URIEncodedFormat $uri 253 | } 254 | 255 | # Debug the encoded URI 256 | Write-Verbose "[DEBUG:Find-Network] ENC-URI '$uri'" 257 | } 258 | 259 | END { 260 | Write-Debug "[DEBUG:Find-Network] End" 261 | # Send the request and print any error messages 262 | try { 263 | $local_results = Invoke-RestMethod -Uri $uri -Method Get -WebSession $script:ib_session 264 | } catch { 265 | Write-Error "[ERROR:Find-Network] There was an error performing the network search." 266 | # $_.ErrorDetails is absolutely useless here 267 | #Write-Host $_.ErrorDetails 268 | 269 | # Get the actual message provided by Infoblox 270 | $result = $_.Exception.Response.GetResponseStream() 271 | $reader = New-Object System.IO.StreamReader($result) 272 | $reader.BaseStream.Position = 0 273 | $reader.DiscardBufferedData() 274 | $responseBody = $reader.ReadToEnd() 275 | Write-Error "[ERROR:Find-Network] $responseBody" 276 | 277 | return $false 278 | } 279 | 280 | return $local_results 281 | } 282 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Get-Network.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Get an Infoblox network based on the reference passed. 4 | 5 | .Description 6 | Get the referenced network from the Grid database. 7 | 8 | .Parameter _ref 9 | The network reference obtained from a 'find' operation 10 | 11 | .Parameter return_fields 12 | A list of comma separated return fields to be included in the results. 13 | 14 | .Parameter json 15 | Converts the data results to JSON format on return 16 | 17 | .Outputs 18 | An object array of name/value pairs 19 | 20 | .Example 21 | Get-Network $ref 22 | 23 | Get a network that has the reference indicated 24 | 25 | #> 26 | 27 | function script:Get-Network { 28 | Param ( 29 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] 30 | [string]$_ref, 31 | [Parameter(Mandatory=$false,Position=1)] 32 | [string]$return_fields = "comment,extattrs,members", 33 | [Parameter(Mandatory=$false,Position=2)] 34 | [switch]$json 35 | ) 36 | 37 | BEGIN { 38 | Write-Debug "[DEBUG:Get-Network] Begin" 39 | [hashtable[]]$data_array = $null 40 | } 41 | 42 | PROCESS { 43 | Write-Verbose "[Get-Network] [$_ref] [$return_fields] [$json]" 44 | 45 | # Get the data being requested 46 | Write-Debug "[DEBUG:Get-Network] Retrieve network object" 47 | $local_results = Get-Object -_ref $_ref -_return_fields $return_fields 48 | 49 | # Add the data to our array 50 | Write-Debug "[DEBUG:Get-Network] Append results with previous" 51 | $data_array += $local_results 52 | } 53 | 54 | END { 55 | if ($json) { 56 | Write-Debug "[DEBUG:Get-Network] return results in JSON format" 57 | return $data_array | ConvertTo-JSON -Depth 4 58 | } else { 59 | Write-Debug "[DEBUG:Get-Network] return results" 60 | return $data_array 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Get-Schema.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Retrieves the schema object from the Grid and displays it 4 | 5 | .DESCRIPTION 6 | Retrieves the schema object from the Grid and displays it 7 | 8 | .Parameter objType 9 | Retrieves the schema for the selected object type and displays it 10 | 11 | .OUTPUTS 12 | Shows schema data from the Grid 13 | 14 | .EXAMPLE 15 | Show-Schema 16 | 17 | #> 18 | 19 | function script:Get-Schema { 20 | Param ( 21 | [Parameter(Mandatory=$false,Position=0)] 22 | [string]$objType 23 | ) 24 | 25 | BEGIN { 26 | Write-Debug "[DEBUG:Get-Schema] Begin" 27 | } 28 | 29 | PROCESS { 30 | } 31 | 32 | END { 33 | # Set the URI to retrieve the Grid object 34 | if (! [string]::IsNullorEmpty($objType)) { 35 | $uri = $script:ib_uri_base + $objType + "?_schema" 36 | } else { 37 | $uri = $script:ib_uri_base + "?_schema" 38 | } 39 | Write-Debug "[DEBUG:Get-Schema] URI = $uri" 40 | 41 | # Make a connection to the Grid and print the detailed error message as necessary 42 | try { 43 | $schema_obj = Invoke-RestMethod -Uri $uri -Method Get -WebSession $script:ib_session 44 | } catch { 45 | Write-Error '[ERROR:Get-Schema] There was an error retrieving the schema.' 46 | # $_.ErrorDetails is absolutely useless here 47 | #Write-Host $_.ErrorDetails 48 | 49 | # Get the actual message provided by Infoblox 50 | $result = $_.Exception.Response.GetResponseStream() 51 | $reader = New-Object System.IO.StreamReader($result) 52 | $reader.BaseStream.Position = 0 53 | $reader.DiscardBufferedData() 54 | $responseBody = $reader.ReadToEnd() 55 | Write-Error [ERROR:Get-Schema] $responseBody 56 | 57 | return $false 58 | } 59 | 60 | Write-Debug "[DEBUG:Get-Schema] $schema_obj" 61 | return $schema_obj 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Set-MaxResults.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Allows changing maximum number of results returned from a query. 4 | 5 | .Description 6 | Used to change the maximum number of records/results returned from a NIOS query. 7 | 8 | .Parameter max_results 9 | Requires a positive number value to be provided. 10 | 11 | .Outputs 12 | Updated max results value 13 | 14 | .Example 15 | Set-MaxResults 10000 16 | 17 | MaxResults: '10000' 18 | 19 | #> 20 | 21 | function script:Set-MaxResults { 22 | Param ( 23 | [Parameter(Mandatory=$true,Position=0)] 24 | [int]$max_results 25 | ) 26 | 27 | BEGIN { 28 | Write-Debug "[DEBUG:Set-MaxResults] Begin" 29 | $okay = $false 30 | } 31 | 32 | PROCESS { 33 | # Validate that the string was submitted correctly 34 | if (($max_results -gt 0) -and ($max_results -lt 1000001)) { 35 | Write-Debug "[DEBUG:Set-MaxResults] Changing max results from '$script:ib_max_results' to '$max_results'" 36 | $okay = $true 37 | } else { 38 | Write-Error "[ERROR:Set-MaxResults] You must enter a value >0 and <=1000000." 39 | } 40 | } 41 | 42 | END { 43 | if ($okay) { 44 | $script:ib_max_results = $max_results 45 | Write-Host "MaxResults : '$script:ib_max_results'" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Set-WapiVersion.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Allows changing the WAPI version. 4 | 5 | .Description 6 | The WAPI version may need to change for some functions that perform differently between versions 7 | 8 | .Parameter wapi_ver 9 | Requires the new string be entered in "vX.Y" format 10 | 11 | .Outputs 12 | Updated URI value 13 | 14 | .Example 15 | # Sets the WAPI version to the value provided 16 | Set-WapiVersion "v2.3.1" 17 | 18 | WAPI Version: 'v2.3.1' 19 | URI Base : 'https://192.168.1.2/wapi/v2.3.1' 20 | 21 | .Example 22 | # Automatically sets the WAPI version to the highest supported 23 | Set-WapiVersion 24 | 25 | WAPI Version: 'v2.3.1' 26 | URI Base : 'https://192.168.1.2/wapi/v2.3.1' 27 | #> 28 | 29 | function script:Set-WapiVersion { 30 | Param ( 31 | [Parameter(Mandatory=$false,Position=0)] 32 | [string]$wapi_ver = $null 33 | ) 34 | 35 | BEGIN { 36 | Write-Debug "[DEBUG:Set-WapiVersion] Begin" 37 | $okay = $false 38 | } 39 | 40 | PROCESS { 41 | # Determine if we need to retrieve the WAPI version from the schema 42 | if ([string]::IsNullOrEmpty($wapi_ver)) { 43 | # Get the highest version supported by the Grid 44 | Write-Debug "[DEBUG:Set-WapiVersion] No version string provided. Getting latest from the schema." 45 | 46 | $ibschema = Get-IBSchema 47 | if ($ibschema -eq $false) { 48 | # We have some error condition; abort 49 | Write-Debug "[DEBUG:Set-WapiVersion] Error retrieving schema. Can't set WAPI version." 50 | } 51 | else { 52 | $lastItem = $ibschema.supported_versions.Count - 1 53 | $highestVersion = $ibschema.supported_versions.Item($lastItem) 54 | $wapi_ver = "v" + $highestVersion 55 | Write-Verbose "[Set-WapiVersion] Automatically selected '$wapi_ver' from the schema" 56 | } 57 | } 58 | 59 | # Validate that the string is in the correct format 60 | if ($wapi_ver -match "v[1-9]{1,}\.*[0-9]*") { 61 | Write-Debug "[DEBUG:Set-WapiVersion] '$wapi_ver' matched regex" 62 | Write-Verbose "[Set-WapiVersion] Changing WAPI version from '$script:ib_wapi_ver' to '$wapi_ver'" 63 | $okay = $true 64 | } 65 | else { 66 | Write-Debug "[DEBUG:Set-WapiVersion] No match on regex and not null: '$wapi_ver'" 67 | Write-Error "[ERROR:Set-WapiVersion] You entered a WAPI version string in the wrong format. Try 'v#.#' (for example, v1.3)." 68 | } 69 | } 70 | 71 | END { 72 | if ($okay) { 73 | $script:ib_wapi_ver = $wapi_ver 74 | Write-Host "WAPI Version: '$script:ib_wapi_ver'" 75 | 76 | $script:ib_uri_base = "https://$script:ib_grid_master/wapi/$script:ib_wapi_ver/" 77 | Write-Host "URI Base : '$script:ib_uri_base'" 78 | } 79 | 80 | return $okay 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Infoblox-DDI/Public/Show-SessionVariables.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Show the values that are being used by the script for the active session 4 | 5 | .Description 6 | Show values for all of the "script" local variables that are used during various connection attempts. 7 | 8 | .Outputs 9 | Simple table of values 10 | 11 | #> 12 | 13 | function script:Show-SessionVariables { 14 | BEGIN { 15 | Write-Debug "[DEBUG:Show-SessionVariables] Begin" 16 | } 17 | 18 | PROCESS { 19 | } 20 | 21 | END { 22 | Write-Host "Grid Master : '$script:ib_grid_master'" 23 | Write-Host "Grid Name : '$script:ib_grid_name'" 24 | Write-Host "Grid Ref : '$script:ib_grid_ref'" 25 | Write-Host "Max Results : '$script:ib_max_results'" 26 | Write-Host "URI Base : '$script:ib_uri_base'" 27 | Write-Host "Username : '$script:ib_username'" 28 | Write-Host "WAPI Version: '$script:ib_wapi_ver'" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Infoblox-DDI/Sample.ps1: -------------------------------------------------------------------------------- 1 | # Remove the module if loaded so we can reload it 2 | Get-Module Infoblox-DDI | Remove-Module 3 | clear 4 | 5 | # Load the current module 6 | Import-Module .\Infoblox-DDI.psd1 7 | Write-Host "" 8 | Get-Command -Module Infoblox-DDI 9 | Write-Host "" 10 | 11 | #$GridMaster = Read-Host "Grid Master" 12 | #$Username = Read-Host "Username" 13 | #Connect-IBGridMaster $GridMaster $Username -ask -force 14 | #Connect-IBGridmaster demogm1.infoblox.com dsmith -ask -force 15 | #Connect-IBGridMaster 172.16.98.15 admin infoblox -force 16 | Connect-IBGridMaster 172.16.98.16 admin infoblox -force 17 | 18 | Show-IBSessionVariables 19 | Write-Host "" 20 | 21 | $schema_obj = Get-IBSchema 22 | Write-Host "Objects supported by WAPI version: ", $schema_obj.supported_objects.Count 23 | 24 | # Could do checks to see if objects are supported by the current/in use WAPI version before acting on them 25 | #if ($schema_obj.supported_objects.Contains("network") -eq $true) {} else {} 26 | #if ($schema_obj.supported_objects.Contains("network") -eq $true) { Write-Host "1" } else { Write-Host "0" } 27 | 28 | 29 | # Fail tests 30 | #Write-Host "Fail Tests" 31 | #Set-IBMaxResults 0 32 | #Set-IBMaxResults 1000001 33 | #Set-IBWapiVersion "1.7" 34 | #Set-IBWapiVersion "v 1.7" 35 | 36 | # Success tests 37 | #Write-Host "Success Tests" 38 | Set-IBMaxResults 10 39 | #Set-IBWapiVersion "v1.7" 40 | #Set-IBWapiVersion 41 | 42 | Write-Host "Find all networks starting with '192.168'" 43 | Find-IBNetwork -return_fields "extattrs" -network 192.168 44 | 45 | Write-Host "Find network '192.168.1.0'" 46 | Find-IBNetwork -return_fields "extattrs" -network 192.168.1.0 -network_exact_match 47 | 48 | Write-Host "Find networks starting with 'Test' in the comment" 49 | Find-IBNetwork -return_fields "extattrs" -comment Test -comment_match_type ~= 50 | 51 | Write-Host "Find networks with 'Test Internal 1' in the comment" 52 | Find-IBNetwork -return_fields "extattrs" -comment "Test Internal 1" 53 | 54 | Write-Host "Find networks with 'test internal 1' in the comment (case insensitive)" 55 | Find-IBNetwork -return_fields "extattrs" -comment "test internal 1" -comment_match_type := 56 | 57 | Write-Host "Find networks with 'test' in the comment (case insensitive)" 58 | Find-IBNetwork -return_fields "extattrs" -comment test -comment_match_type ~:= -network_view "Company 1" 59 | 60 | Write-Host "Find all networks in the 'default' network view" 61 | Find-IBNetwork -return_fields "extattrs" -network_view default 62 | 63 | Write-Host "Find all networks in the 'Company 1' network view" 64 | Find-IBNetwork -return_fields "extattrs" -network_view "Company 1" 65 | 66 | Write-Host "Find all networks starting with '192.168' where the Country is 'US'" 67 | Find-IBNetwork -return_fields "extattrs" -network 192.168 -search_string "*Country=US" 68 | 69 | Write-Host "Find the smallest network (from the default view) that contains the IP address '192.168.0.5'" 70 | Find-IBNetwork -return_fields "extattrs" -contains_address 192.168.0.5 71 | 72 | Write-Host "Find all unmanaged networks" 73 | Find-IBNetwork -unmanaged 74 | 75 | Write-Host "Find all networks in network container 25.25.0.0/16" 76 | Find-IBNetwork -network_container 25.25.0.0/16 77 | 78 | Write-Host "Find networks where the EA 'Country' does not equal 'US'" 79 | Find-IBNetwork -return_fields "extattrs" -search_string "*Country!=US" -Verbose 80 | 81 | #Write-Host "Get network with ref" 82 | #$test_data = Get-IBNetwork network/ZG5zLm5ldHdvcmskMTkyLjE2OC4xLjAvMjQvMA:192.168.1.0/24/Company%201 -json 83 | #$test_data 84 | 85 | #Get-IBSchema network | ConvertTo-Json 86 | 87 | 88 | 89 | ################################################ 90 | # 91 | # Lots of stuff below for testing. 92 | # Need to clean up the object because not all of the values can be written back to the server. 93 | # Maybe loop through the fields and check the schema to see which need to be "removed" from the object to send back 94 | # 95 | ################################################ 96 | 97 | 98 | # Get some valid network object and loop through the EAs 99 | $mynet1 = Get-IBNetwork network/ZG5zLm5ldHdvcmskMTcyLjE2Ljk4LjAvMjQvMg:172.16.98.0/24/Company%201 -return_fields "disable,extattrs,netmask,network_container,extattrs" 100 | 101 | # Grab the existing EAs 102 | $mykeys = $mynet1.extattrs.Keys 103 | $myEAArray = @{} 104 | foreach ($key in $mykeys) { 105 | $myEA = @{} 106 | $myEA.Add("value", $mynet1.extattrs.$key.value) 107 | $myEAArray.Add($key, $myEA) 108 | } 109 | 110 | # Add a new EA (State = CA) to the network 111 | $myEAArray | ConvertTo-Json 112 | $myEAArray += Add-IBExtensibleAttribute "State" "CA" 113 | $myEAArray | ConvertTo-Json 114 | 115 | # Create the new object to store the data to write 116 | $myNewObject = @{} 117 | $myNewObject | Add-Member -Name "comment" -Value $mynet1.comment -MemberType NoteProperty 118 | $myNewObject | Add-Member -Name "disable" -Value $mynet1.disable -MemberType NoteProperty 119 | $myNewObject | Add-Member -Name "extattrs" -Value $myEAArray -MemberType NoteProperty 120 | $jsonData = $myNewObject | ConvertTo-Json 121 | 122 | # Establish our update URI and credentials 123 | $uri = "https://172.16.98.16/wapi/v2.5/network/ZG5zLm5ldHdvcmskMTcyLjE2Ljk4LjAvMjQvMg:172.16.98.0/24/Company%201" 124 | $uri 125 | $securePwd = ConvertTo-SecureString "infoblox" -AsPlainText -Force 126 | $credential = New-Object System.Management.Automation.PSCredential ("admin", $securePwd) 127 | 128 | try { 129 | $response = Invoke-RestMethod -Uri $uri -Method Put -ContentType 'application/json' -Body $jsonData -Credential $credential 130 | } catch { 131 | # Get the actual message provided by Infoblox 132 | $result = $_.Exception.Response.GetResponseStream() 133 | $reader = New-Object System.IO.StreamReader($result) 134 | $reader.BaseStream.Position = 0 135 | $reader.DiscardBufferedData() 136 | $responseBody = $reader.ReadToEnd() 137 | Write-Error "[ERROR] $responseBody" 138 | } 139 | 140 | $response 141 | 142 | # Curl commands to update/restore EA settings 143 | #curl -k1 -u admin:infoblox -X PUT https://172.16.98.16/wapi/v2.5/network/ZG5zLm5ldHdvcmskMTcyLjE2Ljk4LjAvMjQvMg:172.16.98.0/24/Company%201 -d '{ "extattrs": { "Country": { "value": "CA" }, "Site": { "value": "Toronto"}, "State": { "value": "CA" }}}' -H "Content-Type: application/json" 144 | #curl -k1 -u admin:infoblox -X PUT https://172.16.98.16/wapi/v2.5/network/ZG5zLm5ldHdvcmskMTcyLjE2Ljk4LjAvMjQvMg:172.16.98.0/24/Company%201 -d '{ "extattrs": { "Country": { "value": "CA" }, "Site": { "value": "Toronto"}}}' -H "Content-Type: application/json" 145 | 146 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Infoblox-API 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | REST-PowerShell 2 | ======================= 3 | 4 | PowerShell examples and wrapper for the Infoblox REST API 5 | 6 | This repository is intended for Infoblox customers, partners and employees who which to share in the development and maintanence of scripts using the REST API from PowerShell. 7 | 8 | For support and general discussion, please go the Infoblox Community website. http://community.infoblox.com 9 | 10 | To contribute, please create a fork, then define your own branch (or use dev) and code your changes. When you are happy with your code, please send us a pull request with your updates. 11 | 12 | 13 | Please refer to Ameritus/PowerShell for the most up to date copy. 14 | -------------------------------------------------------------------------------- /examples/ib_get-range.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 3 2 | 3 | ########## 4 | # 5 | # Author: Don Smith 6 | # Email : don@infoblox.com 7 | # : smithdonalde@gmail.com 8 | # This script is provided as is. Use at your own risk. 9 | 10 | ########## 11 | # 12 | # Remember to enable powershell scripts to run on your system 13 | # example >> Set-ExecutionPolicy -ExecutionPolicy Unrestricted 14 | # 15 | 16 | ########## 17 | # Default values and command line parameters 18 | # switch ask_pw will securely prompt for the password 19 | # Standardize the following options: 20 | # g = grid_master, u = username, p = password, a = ask_pw, d = debug 21 | # Assume all other options would need fully qualification 22 | Param ( 23 | [string]$grid_master = "192.168.1.2", 24 | [string]$username = "admin", 25 | [string]$password = "infoblox", 26 | [string]$outfile = "get-range.csv", 27 | [string]$wapi_ver = "v1.2", 28 | [string]$max_results = "_max_results=10000", 29 | [switch]$ask_pw, 30 | [switch]$json, 31 | [switch]$debug, 32 | [string]$x, 33 | [string]$fields 34 | ) 35 | Write-Output "" 36 | 37 | $dbg_time_elapsed = [System.Diagnostics.Stopwatch]::StartNew() 38 | 39 | ########## 40 | # Set defaults 41 | $def_rfields = "network,start_addr,end_addr,comment,network_view" 42 | 43 | ########## 44 | # Build the values that need built 45 | if ($ask_pw) { 46 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 47 | Write-Output "" 48 | } else { 49 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 50 | } 51 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 52 | $uri_base = "https://$grid_master/wapi/$wapi_ver" 53 | 54 | if (!$x) { 55 | $x = $( Read-Host -Prompt "Enter a valid search string" ) 56 | } 57 | 58 | ########## 59 | # Do the following to ignore self-signed certificates 60 | add-type @" 61 | using System.Net; 62 | using System.Security.Cryptography.X509Certificates; 63 | public class TrustAllCertsPolicy : ICertificatePolicy { 64 | public bool CheckValidationResult( 65 | ServicePoint srvPoint, X509Certificate certificate, 66 | WebRequest request, int certificateProblem) { 67 | return true; 68 | } 69 | } 70 | "@ 71 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 72 | 73 | ########################## 74 | ########## MAIN ########## 75 | ########################## 76 | 77 | # Search for the object reference 78 | $uri_search = "search"+'?'+"objtype=range&search_string~=$x" 79 | $uri = "$uri_base/$uri_search" 80 | try { 81 | $results = Invoke-RestMethod -Uri $uri -Credential $credential -Method Get -SessionVariable ib_session 82 | } catch { 83 | write-host $_.ErrorDetails 84 | exit 1 85 | } 86 | 87 | # Get just the references and then loop to grab the data 88 | $my_results = $results | Select "_ref" 89 | 90 | $count = $results.count 91 | Write-Output "Authenticating as: $username" 92 | Write-Output "Base URI : $uri_base" 93 | Write-Output "Search URI : $uri_search" 94 | Write-Output "Full URI : $uri" 95 | 96 | foreach ($record in $my_results) { 97 | $ref = $( $record._ref ) 98 | if ($fields) { 99 | $rfields = "$def_rfields,$fields" 100 | } else { 101 | $rfields = $def_rfields 102 | } 103 | $uri = "$uri_base/$ref"+'?'+"_return_fields=$rfields" 104 | Write-Output "Object URI : $uri" 105 | $results = Invoke-RestMethod -Uri "$uri" -Method Get -Websession $ib_session 106 | 107 | if ((!$debug) -and ($count -gt 0)) { 108 | if ($json) { 109 | $results | Out-File -FilePath $outfile -Append 110 | } else { 111 | $results | Export-Csv $outfile -NoTypeInformation -Encoding UTF8 112 | } 113 | } else { 114 | $results 115 | } 116 | } 117 | 118 | Write-Output "" 119 | 120 | if ($debug) { 121 | Write-Host "Total time elapsed: $($dbg_time_elapsed.Elapsed.ToString())" 122 | } 123 | -------------------------------------------------------------------------------- /examples/ib_list-ranges.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 3 2 | 3 | ########## 4 | # 5 | # Author: Don Smith 6 | # Email : don@infoblox.com 7 | # : smithdonalde@gmail.com 8 | # This script is provided as is. Use at your own risk. 9 | 10 | ########## 11 | # 12 | # Remember to enable powershell scripts to run on your system 13 | # example >> Set-ExecutionPolicy -ExecutionPolicy Unrestricted 14 | # 15 | 16 | ########## 17 | # Default values and command line parameters 18 | # switch ask_pw will securely prompt for the password 19 | # Standardize the following options: 20 | # g = grid_master, u = username, p = password, a = ask_pw, d = debug 21 | # Assume all other options would need fully qualification 22 | Param ( 23 | [string]$grid_master = "192.168.1.2", 24 | [string]$username = "admin", 25 | [string]$password = "infoblox", 26 | [string]$outfile = "list-ranges.csv", 27 | [string]$wapi_ver = "v1.0", 28 | [string]$max_results = "_max_results=10000", 29 | [switch]$ask_pw, 30 | [switch]$json, 31 | [switch]$debug 32 | ) 33 | Write-Output "" 34 | 35 | $dbg_time_elapsed = [System.Diagnostics.Stopwatch]::StartNew() 36 | 37 | ########## 38 | # Set defaults 39 | 40 | ########## 41 | # Build the values that need built 42 | if ($ask_pw) { 43 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 44 | Write-Output "" 45 | } else { 46 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 47 | } 48 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 49 | $uri_base = "https://$grid_master/wapi/$wapi_ver" 50 | 51 | 52 | ########## 53 | # Do the following to ignore self-signed certificates 54 | add-type @" 55 | using System.Net; 56 | using System.Security.Cryptography.X509Certificates; 57 | public class TrustAllCertsPolicy : ICertificatePolicy { 58 | public bool CheckValidationResult( 59 | ServicePoint srvPoint, X509Certificate certificate, 60 | WebRequest request, int certificateProblem) { 61 | return true; 62 | } 63 | } 64 | "@ 65 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 66 | 67 | ########################## 68 | ########## MAIN ########## 69 | ########################## 70 | 71 | $currentScriptName = $MyInvocation.MyCommand.Name 72 | write-host "script: $currentScriptName" 73 | 74 | 75 | # Request the transaction (GET request for data) 76 | $uri = "$uri_base/range" 77 | try { 78 | $results = Invoke-RestMethod -Uri $uri -Credential $credential -Method Get -SessionVariable ib_session 79 | } catch { 80 | write-host $_.ErrorDetails 81 | exit 1 82 | } 83 | 84 | $count = $results.count 85 | Write-Output "Authenticating as : $username" 86 | Write-Output "Full URI : $uri" 87 | Write-Output "Number of records retrieved: $count" 88 | 89 | if ((!$debug) -and ($count -gt 0)) { 90 | if ($json) { 91 | $results | Out-File -FilePath $outfile #-NoClobber 92 | } else { 93 | $results | Export-Csv $outfile -NoTypeInformation -Encoding UTF8 #-NoClobber 94 | } 95 | 96 | Write-Output "Saved file to : $outfile" 97 | } else { 98 | $results 99 | } 100 | Write-Output "" 101 | 102 | if ($debug) { 103 | Write-Host "Total time elapsed: $($dbg_time_elapsed.Elapsed.ToString())" 104 | } 105 | -------------------------------------------------------------------------------- /examples/ib_search.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 3 2 | 3 | ########## 4 | # 5 | # Author: Don Smith 6 | # Email : don@infoblox.com 7 | # : smithdonalde@gmail.com 8 | # This script is provided as is. Use at your own risk. 9 | 10 | ########## 11 | # 12 | # Remember to enable powershell scripts to run on your system 13 | # example >> Set-ExecutionPolicy -ExecutionPolicy Unrestricted 14 | # 15 | 16 | ########## 17 | # Default values and command line parameters 18 | # switch ask_pw will securely prompt for the password 19 | # Standardize the following options: 20 | # g = grid_master, u = username, p = password, a = ask_pw, d = debug 21 | # Assume all other options would need fully qualification 22 | Param ( 23 | [string]$grid_master = "192.168.1.2", 24 | [string]$username = "admin", 25 | [string]$password = "infoblox", 26 | [string]$outfile = "search-results.csv", 27 | [string]$wapi_ver = "v1.2", 28 | [string]$max_results = "_max_results=10000", 29 | [string]$search_str = ".*", 30 | [string]$type = "range", 31 | [switch]$ask_pw, 32 | [switch]$json, 33 | [switch]$debug 34 | ) 35 | Write-Output "" 36 | 37 | $dbg_time_elapsed = [System.Diagnostics.Stopwatch]::StartNew() 38 | 39 | ########## 40 | # Set defaults 41 | $search_type = $type 42 | $search_string = $x 43 | 44 | ########## 45 | # Build the values that need built 46 | if ($ask_pw) { 47 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 48 | Write-Output "" 49 | } else { 50 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 51 | } 52 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 53 | $uri_base = "https://$grid_master/wapi/$wapi_ver" 54 | 55 | 56 | ########## 57 | # Do the following to ignore self-signed certificates 58 | add-type @" 59 | using System.Net; 60 | using System.Security.Cryptography.X509Certificates; 61 | public class TrustAllCertsPolicy : ICertificatePolicy { 62 | public bool CheckValidationResult( 63 | ServicePoint srvPoint, X509Certificate certificate, 64 | WebRequest request, int certificateProblem) { 65 | return true; 66 | } 67 | } 68 | "@ 69 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 70 | 71 | ########################## 72 | ########## MAIN ########## 73 | ########################## 74 | 75 | # Request the transaction (GET request for data) 76 | $uri = "$uri_base/search"+'?'+"objtype=$search_type"+'&'+"search_string~=$search_str" 77 | try { 78 | $results = Invoke-RestMethod -Uri $uri -Credential $credential -Method Get -SessionVariable ib_session 79 | } catch { 80 | write-host $_.ErrorDetails 81 | exit 1 82 | } 83 | 84 | $count = $results.count 85 | Write-Output "Authenticating as : $username" 86 | Write-Output "Base URI : $uri" 87 | Write-Output "Number of records retrieved: $count" 88 | 89 | if ((!$debug) -and ($count -gt 0)) { 90 | if ($json) { 91 | $results | Out-File -FilePath $outfile #-NoClobber 92 | } else { 93 | $results | Export-Csv $outfile -NoTypeInformation -Encoding UTF8 #-NoClobber 94 | } 95 | Write-Output "Saved file to : $outfile" 96 | } else { 97 | $results 98 | } 99 | 100 | Write-Output "" 101 | 102 | if ($debug) { 103 | Write-Host "Total time elapsed: $($dbg_time_elapsed.Elapsed.ToString())" 104 | } 105 | -------------------------------------------------------------------------------- /examples/site-creation-in-container.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 3 2 | 3 | ########## 4 | # 5 | # Author: Nicolas Jeanselme 6 | # Email : njeanselme@infoblox.com 7 | # This script is provided as is. Use at your own risk. 8 | 9 | ########## 10 | # 11 | # Remember to enable powershell scripts to run on your system 12 | # example >> Set-ExecutionPolicy -ExecutionPolicy Unrestricted 13 | # 14 | 15 | ########## 16 | # Default values and command line parameters 17 | # switch ask_pw will securely prompt for the password 18 | # Standardize the following options: 19 | # g = grid_master, u = username, p = password, a = ask_pw, d = debug 20 | # Assume all other options would need fully qualification 21 | Param ( 22 | [string]$grid_master = "192.168.1.2", 23 | [string]$username = "admin", 24 | [string]$password = "infoblox", 25 | [string]$wapi_ver = "v1.6", 26 | [string]$max_results = "_max_results=10000", 27 | [string]$network = "3.0.0.0/22", 28 | [int]$vlan = 1500, 29 | [array]$site_structure, 30 | [switch]$ask_pw, 31 | [switch]$json, 32 | [switch]$debug 33 | ) 34 | 35 | $site_structure=@{"cidr"=25;"num"=2},@{"cidr"=28;"num"=16},@{"cidr"=24;"num"=2} 36 | 37 | write-host "Parameters set" 38 | 39 | $dbg_time_elapsed = [System.Diagnostics.Stopwatch]::StartNew() 40 | 41 | ########## 42 | # Set defaults 43 | 44 | ########## 45 | # Build the values that need built 46 | if ($ask_pw) { 47 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 48 | Write-Output "" 49 | } else { 50 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 51 | } 52 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 53 | $uri_base = "https://$grid_master/wapi/$wapi_ver" 54 | 55 | ########## 56 | # Do the following to ignore self-signed certificates 57 | add-type @" 58 | using System.Net; 59 | using System.Security.Cryptography.X509Certificates; 60 | public class TrustAllCertsPolicy : ICertificatePolicy { 61 | public bool CheckValidationResult( 62 | ServicePoint srvPoint, X509Certificate certificate, 63 | WebRequest request, int certificateProblem) { 64 | return true; 65 | } 66 | } 67 | "@ 68 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 69 | 70 | #[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } 71 | 72 | ########################## 73 | ########## MAIN ########## 74 | ########################## 75 | 76 | $currentScriptName = $MyInvocation.MyCommand.Name 77 | write-host "script: $currentScriptName" 78 | 79 | 80 | ########## Get network container ref ########## 81 | 82 | 83 | # Request the transaction (GET request for data) 84 | $uri = "$uri_base/networkcontainer?network=$network" 85 | 86 | try { 87 | $results = Invoke-RestMethod -Uri $uri -Credential $credential -Method Get -SessionVariable ib_session 88 | } catch { 89 | write-host $_.ErrorDetails 90 | write-host $_.Exception 91 | exit 1 92 | } 93 | 94 | $ref = $results._ref 95 | write-host "Authenticating as : $username" 96 | 97 | ########## Get next available networks & create it ########## 98 | 99 | foreach ($block in $site_structure) { 100 | 101 | $uri = $uri_base+"/"+$ref+"?_function=next_available_network&cidr="+$block.cidr+"&num="+$block.num 102 | 103 | try { 104 | $results = Invoke-RestMethod -Uri $uri -Method Post -WebSession $ib_session 105 | } catch { 106 | write-host $results 107 | write-host $_.ErrorDetails 108 | write-host $_.Exception 109 | exit 1 110 | } 111 | Write-Output "Availables: $($results.networks)" 112 | 113 | foreach ($network in $results.networks) { 114 | $uri = $uri_base+"/network?network="+$network 115 | 116 | try { 117 | $results = Invoke-RestMethod -Uri $uri -Method Post -WebSession $ib_session 118 | } catch { 119 | write-host $results 120 | write-host $_.ErrorDetails 121 | write-host $_.Exception 122 | exit 1 123 | } 124 | Write-Output "Created successfully $network" 125 | 126 | 127 | ##### Handle Extensible Attributes ##### 128 | # Now update the object with the extensible attribute data 129 | # This data cannot be submitted when creating the object 130 | $extattrs = @{ 131 | extattrs = @{ 132 | Site = @{ value = "test" }; 133 | VLAN = @{ value = "$vlan" }; 134 | } 135 | } 136 | $json_text = $extattrs | ConvertTo-Json 137 | $uri = $uri_base+"/$results" 138 | 139 | try { 140 | $results = Invoke-RestMethod -Uri $uri -ContentType "application/json" -Body $json_text -Method PUT -WebSession $ib_session 141 | } catch { 142 | write-host $results 143 | Write-Host $_.ErrorDetails 144 | Write-Host $_.Exception 145 | } 146 | 147 | } 148 | } 149 | 150 | if ($debug) { 151 | Write-Host "Total time elapsed: $($dbg_time_elapsed.Elapsed.ToString())" 152 | } 153 | -------------------------------------------------------------------------------- /wrapper/Infoblox.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 4 2 | 3 | ######################################## 4 | # 5 | # Author: Don Smith 6 | # Email : don@infoblox.com 7 | # : smithdonalde@gmail.com 8 | # This script is provided as is. Use at your own risk. 9 | # 10 | 11 | 12 | <# 13 | 14 | TO DO: 15 | - Fix update function (not sure how as the JSON parser appears broken on the server) 16 | - Fix create function (when assigning with an EA) 17 | - Figure out how to make GET function work with direct output of multi-add 18 | - Maybe just do the GET right after the ADD then append to the array 19 | 20 | #> 21 | 22 | ######################################## 23 | # 24 | # Remember to enable powershell scripts to run on your system 25 | # example >> Set-ExecutionPolicy -ExecutionPolicy Unrestricted 26 | # 27 | [CmdletBinding()] 28 | Param () 29 | 30 | ######################################## 31 | # 32 | # NOTES 33 | # Global Variables 34 | # $ib_* are set in IB-Create-Session 35 | # Functions 36 | # All begin with "IB-" 37 | # 38 | ######################################## 39 | $script:ib_script_revision = "2013-11-19 v1.11.19" 40 | 41 | 42 | ######################################## 43 | # 44 | # UTILITY FUNCTIONS 45 | # 46 | ######################################## 47 | 48 | function script:IB-ConvertFrom-JSON { 49 | <# 50 | .SYNOPSIS 51 | Uses the JavaScript serializer object. 52 | #> 53 | Param ( 54 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 55 | $json 56 | ) 57 | 58 | BEGIN { 59 | Write-Verbose '[convert-from-json] Begin' 60 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 61 | $data_array = @() 62 | } 63 | 64 | PROCESS { 65 | $data = $ser.DeSerializeObject($json) 66 | $data_array += $data 67 | } 68 | 69 | END { 70 | return $data_array 71 | } 72 | } 73 | 74 | function script:IB-ConvertTo-JSON { 75 | <# 76 | .SYNOPSIS 77 | Uses the JavaScript serializer object. The built-in PS ConvertTo-Json script is broken for nested extattr information. 78 | #> 79 | Param ( 80 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 81 | $data 82 | ) 83 | 84 | BEGIN { 85 | Write-Verbose '[convert-to-json] Begin' 86 | $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 87 | $data_array = @() 88 | } 89 | 90 | PROCESS { 91 | $json = $ser.Serialize($data) 92 | $data_array += $json 93 | } 94 | 95 | END { 96 | return $data_array 97 | } 98 | } 99 | 100 | function script:IB-Ignore-Self-Signed-Certs { 101 | ######################################## 102 | # Do the following to ignore self-signed certificates 103 | add-type @" 104 | using System.Net; 105 | using System.Security.Cryptography.X509Certificates; 106 | public class TrustAllCertsPolicy : ICertificatePolicy { 107 | public bool CheckValidationResult( 108 | ServicePoint srvPoint, X509Certificate certificate, 109 | WebRequest request, int certificateProblem) { 110 | return true; 111 | } 112 | } 113 | "@ 114 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 115 | } 116 | 117 | function script:IB-Get-Input-Choice { 118 | Param ( 119 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 120 | [int]$num_choices 121 | ) 122 | 123 | BEGIN { 124 | Write-Verbose "[get-input-choice] range = 1..$num_choices" 125 | } 126 | 127 | PROCESS { } 128 | 129 | END { 130 | # Return the "last" answer if there are fewer than 2 choices 131 | if ($num_choices -lt 2) { 132 | Write-Debug "[dbg] Fewer than 2 choices. Returning '$num_choices'." 133 | return $num_choices 134 | } 135 | 136 | # Zero means quit, otherwise let's get a value from the range of 1 to the highest value 137 | [int]$input_value = -1 138 | while ($input_value -lt 0 -or $input_value -gt $num_choices) { 139 | [int]$input_value = Read-Host "--> Please choose from 1 to $num_choices. Enter '0' (zero) to quit: " 140 | } 141 | return $input_value 142 | } 143 | 144 | } 145 | 146 | function script:IB-Write-Data { 147 | <# 148 | .SYNOPSIS 149 | Displays data in PS default output format for custom objects (name/value pair table). 150 | .PARAMETER data 151 | A data object to display. 152 | 153 | .EXAMPLE 154 | IB-Write-Data $my_data 155 | 156 | Name Value 157 | ---- ----- 158 | field1 field_value1 159 | field2 field_value2 160 | #> 161 | Param ( 162 | [Parameter(Mandatory=$false,ValueFromPipeline=$true)] 163 | [hashtable]$data 164 | ) 165 | 166 | BEGIN { 167 | Write-Verbose '[write-data] Write to host' 168 | } 169 | 170 | PROCESS { 171 | Write-Debug "[dbg] Write-Data : num keys = $( $data.Keys.Count )" 172 | Write-Debug "[dbg] Write-Data : object count = $( $data.Count )" 173 | 174 | if ($data.Keys) { 175 | # We should be dealing with only a single object here 176 | $output = [ordered]@{} 177 | 178 | foreach ($field_name in $data.Keys) { 179 | $field_type = $data.Item($field_name).GetType().Name 180 | 181 | switch -wildcard ($field_type) { 182 | "Object*" { 183 | foreach ($attr in $data.Item($field_name).Keys) { 184 | $my_key = "[$field_name] $attr" 185 | $my_value = $( $data.Item($field_name).$attr.value ) 186 | if (!$my_value) { 187 | $my_value = $( $data.Item($field_name).$attr ) 188 | } 189 | $output.Add( $my_key, $my_value ) 190 | } 191 | } 192 | "Dictionary*" { 193 | foreach ($attr in $data.Item($field_name).Keys) { 194 | $my_key = "[$field_name] $attr" 195 | $my_value = $( $data.Item($field_name).$attr.value ) 196 | if (!$my_value) { 197 | $my_value = $( $data.Item($field_name).$attr ) 198 | } 199 | $output.Add( $my_key, $my_value ) 200 | } 201 | } 202 | "String*" { 203 | $output.Add( $field_name, $( $data.$field_name ) ) 204 | } 205 | default { 206 | $output.Add( $field_name, $( $data.$field_name ) ) 207 | } 208 | } 209 | 210 | } 211 | $output 212 | Write-Host "" 213 | } else { 214 | # It's possible we'll get many objects so let's loop through 215 | foreach ($data_record in $data) { 216 | $output = @{} 217 | $data_record | Get-Member -MemberType *Property | % { 218 | $output.($_.name) = $data_record.($_.name) 219 | } 220 | $output 221 | Write-Host "" 222 | } 223 | } 224 | } 225 | 226 | END { 227 | #Write-Verbose '[write-data] End' 228 | } 229 | 230 | # $data.Keys.Contains("extattrs") | True or False 231 | # $data.Item("extattrs") | displays the value of the object 232 | # $data.Item("name").GetType().Name | Returns the data type of the field 233 | } 234 | 235 | 236 | ######################################## 237 | # 238 | # Infoblox core FUNCTIONS 239 | # Called by helper functions and may be called directly as well 240 | # 241 | ######################################## 242 | 243 | function script:IB-Create-Object { 244 | Param ( 245 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 246 | [hashtable]$record, 247 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 248 | [string]$obj_type 249 | ) 250 | 251 | BEGIN { 252 | Write-Verbose "[create-object] Creating object(s) in Infoblox" 253 | [array]$record_array = @() 254 | } 255 | 256 | PROCESS { 257 | # Prepare the data 258 | $json = $record | IB-ConvertTo-JSON 259 | 260 | # Prepare the URI 261 | $uri = "$ib_uri_base/$obj_type" 262 | Write-Debug "[dbg] $uri" 263 | 264 | # Send the update 265 | try { 266 | $result_ref = Invoke-WebRequest -Uri $uri -ContentType application/json -Method Post -WebSession $ib_session -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) 267 | } catch { 268 | Write-Host "[ERROR] There was an error creating the data." 269 | Write-Host "[ERROR] $uri" 270 | Write-Host $_.ErrorDetails 271 | } 272 | 273 | if ($result_ref) { 274 | [string]$rec_ref = $( IB-ConvertFrom-JSON $result_ref ) 275 | [hashtable]$hash_obj = @{ "_ref" = $rec_ref } 276 | $record_array += $hash_obj 277 | } 278 | } 279 | 280 | END { 281 | return $record_array 282 | } 283 | } 284 | 285 | function script:IB-Create-Session { 286 | <# 287 | .SYNOPSIS 288 | Establishes a session to an Infoblox Grid Master for all subsequent data calls. 289 | .PARAMETER grid_master 290 | A single computer name or IP address. 291 | .EXAMPLE 292 | IB-Create-Session 192.168.1.2 admin infoblox 293 | Creates a connection to a Grid Master using default credentials and IP address. 294 | .EXAMPLE 295 | IB-Create-Session 192.168.1.2 admin -ask_pw 296 | Creates a connection but allows entering the password securely (via prompt with masking). 297 | .NOTES 298 | This should be the first command run to ensure that a connection is established and global variables are properly configured. 299 | #> 300 | Param ( 301 | [Parameter(Mandatory=$false,Position=0)] 302 | [string]$grid_master = "192.168.1.2", 303 | [Parameter(Mandatory=$false,Position=1)] 304 | [string]$username = "admin", 305 | [Parameter(Mandatory=$false,Position=2)] 306 | [string]$password = "infoblox", 307 | [Parameter(Mandatory=$false,Position=3)] 308 | [string]$wapi_ver = "v1.3", 309 | [Parameter(Mandatory=$false,Position=4)] 310 | [string]$max_results = "_max_results=10000", 311 | [Parameter(Mandatory=$false)] 312 | [switch]$ask_pw 313 | ) 314 | 315 | BEGIN { 316 | # Reset all script variables to null until a successful connection is established 317 | $script:ib_grid_name = $null 318 | $script:ib_grid_master = $null 319 | $script:ib_grid_ref = $null 320 | $script:ib_session = $null 321 | $script:ib_uri_base = $null 322 | $script:ib_username = $null 323 | $script:ib_wapi_ver = $null 324 | } 325 | 326 | PROCESS { } 327 | 328 | END { 329 | ########## 330 | # Build the values that need built 331 | if ($ask_pw) { 332 | $secure_pw = $( Read-Host -Prompt "Enter password" -AsSecureString ) 333 | Write-Host "" 334 | } else { 335 | $secure_pw = ConvertTo-SecureString $password -AsPlainText -Force 336 | } 337 | $credential = New-Object System.Management.Automation.PSCredential ($username, $secure_pw) 338 | $uri_base = "https://$grid_master/wapi/$wapi_ver" 339 | Write-Debug "[DEBUG] Create-Session: URI base = $uri_base" 340 | 341 | ########## 342 | # Establish an initial connection 343 | # Exit if there is an error 344 | $uri = "$uri_base/grid" 345 | try { 346 | $grid_obj = Invoke-RestMethod -Uri $uri -Method Get -Credential $credential -SessionVariable new_session 347 | } catch { 348 | Write-Host '[ERROR] There was an error connecting to the Grid.' 349 | Write-Host $_.ErrorDetails 350 | return $false 351 | } 352 | 353 | $s1 = $grid_obj._ref.IndexOf(":") 354 | $grid_name = $grid_obj._ref.Substring( $( $s1 + 1 ) ) 355 | 356 | # Update global variables with new connection information 357 | $script:ib_grid_name = $grid_name 358 | $script:ib_grid_master = $grid_master 359 | $script:ib_grid_ref = $( $grid_obj._ref ) 360 | $script:ib_session = $new_session 361 | $script:ib_uri_base = $uri_base 362 | $script:ib_username = $username 363 | $script:ib_wapi_ver = $wapi_ver 364 | 365 | Write-Verbose "### You are now connected to Grid: '$grid_name' ###" 366 | 367 | return $true 368 | } 369 | } 370 | 371 | function script:IB-Delete-Object { 372 | Param ( 373 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 374 | [hashtable]$record, 375 | # [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] 376 | # [string]$_ref, 377 | [Parameter(Mandatory=$false,ValueFromPipeline=$false)] 378 | [switch]$force 379 | ) 380 | 381 | BEGIN { 382 | [array]$results = @() 383 | } 384 | 385 | PROCESS { 386 | # Prepare the data 387 | $_ref = $record.Item("_ref") 388 | Write-Verbose "[delete-object] $_ref" 389 | 390 | switch ($force) { 391 | $true { 392 | $json = $record | IB-ConvertTo-JSON 393 | Write-Debug "[DEBUG] $json" 394 | 395 | # Prepare the URI 396 | $uri = "$ib_uri_base/$_ref" 397 | Write-Debug "[DEBUG] $uri" 398 | 399 | # Don't do this unless they force me to 400 | if ($force) { 401 | # Send the update 402 | try { 403 | $result_ref = Invoke-WebRequest -Uri $uri -ContentType application/json -Method Delete -WebSession $ib_session -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) 404 | } catch { 405 | Write-Host "[ERROR] There was an error deleting the data." 406 | Write-Host "[ERROR] $uri" 407 | Write-Host $_.ErrorDetails 408 | } 409 | 410 | [string]$rec_ref = $( IB-ConvertFrom-JSON $result_ref ) 411 | [hashtable]$hash_obj = @{ "_ref" = $rec_ref } 412 | $results += $hash_obj 413 | } 414 | } 415 | $false { 416 | Write-Host " >>Nothing deleted but I would have deleted $_ref" 417 | Write-Host " >>-force me next time to do it for real" 418 | } 419 | } 420 | 421 | } 422 | 423 | END { 424 | return $results 425 | } 426 | } 427 | 428 | function script:IB-Get-Object { 429 | Param ( 430 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] 431 | [string]$_ref, 432 | [Parameter(Mandatory=$false)] 433 | [string]$_return_fields 434 | ) 435 | 436 | BEGIN { 437 | if (!$ib_session) { 438 | Write-Host "[ERROR] Try creating a session first. 'IB-Create-Session'" 439 | return $false 440 | } 441 | 442 | # Initialize our counter and hashtable 443 | [hashtable[]]$data_array = $null 444 | } 445 | 446 | PROCESS { 447 | Write-Verbose "[get-object] $_ref" 448 | Write-Debug "[DEBUG] Get-Object: _ref = $_ref" 449 | Write-Debug "[DEBUG] Get-Object: _return_fields = $_return_fields" 450 | 451 | $uri_return_type = "_return_type=json-pretty" 452 | $uri = "$ib_uri_base/$_ref"+'?'+$uri_return_type 453 | 454 | if ($_return_fields) { 455 | $uri = "$uri"+'&'+"_return_fields%2b=$_return_fields" 456 | } 457 | 458 | Write-Debug "[DEBUG-URI] $uri" 459 | 460 | # Try to obtain the data and print an error message if there is one 461 | try { 462 | $local_results = Invoke-WebRequest -Uri $uri -Method Get -WebSession $ib_session 463 | } catch { 464 | Write-Host "[ERROR] There was an error getting the data." 465 | Write-Host "[ERROR-URI] $uri" 466 | Write-Host $_.ErrorDetails 467 | } 468 | 469 | # Grab only the content portion of the returned object 470 | $obj_content = $local_results.Content 471 | 472 | # Deserialize the JSON data into something manageable 473 | $data = $obj_content | IB-ConvertFrom-JSON 474 | 475 | $data_array += $data 476 | } 477 | 478 | END { 479 | return $data_array 480 | } 481 | } 482 | 483 | function script:IB-Search { 484 | Param ( 485 | [Parameter(Mandatory=$false,Position=0)] 486 | [string]$search_string = $( Read-Host -Prompt "Enter a valid search string" ), 487 | [Parameter(Mandatory=$false,Position=1)] 488 | [string]$objtype = $( Read-Host -Prompt "Enter a valid object type" ) 489 | ) 490 | 491 | BEGIN { 492 | # Make sure we already have a session established 493 | if (!$ib_session) { 494 | Write-Host "[ERROR] Try creating a session first. 'IB-Create-Session'" 495 | return $false 496 | } 497 | } 498 | 499 | PROCESS { } 500 | 501 | END { 502 | Write-Verbose "[search] $objtype : $search_string" 503 | # Build the URI 504 | # Search for the object reference 505 | if ($search_string) { $uri_filter = "search_string~=$search_string" } 506 | if ($objtype) { $uri_filter = "$uri_filter"+'&'+"objtype=$objtype" } 507 | $uri = "$ib_uri_base/search"+'?'+"$uri_filter" 508 | Write-Debug "[DEBUG] Search: uri = $uri" 509 | 510 | try { 511 | $results = Invoke-RestMethod -Uri $uri -Method Get -WebSession $ib_session 512 | } catch { 513 | Write-Host "[ERROR] There was an error performing the search." 514 | write-host $_.ErrorDetails 515 | return $false 516 | } 517 | 518 | return $results 519 | } 520 | } 521 | 522 | function script:IB-Show-Examples { 523 | Write-Host "" 524 | Write-Host "###### Infoblox functions loaded" 525 | Write-Host "###### Revision $ib_script_revision" 526 | Write-Host "" 527 | Write-Host "Examples of what you can do now" 528 | Write-Host " IB-Create-Session 192.168.1.2 admin -ask" 529 | Write-Host " `$my_results = IB-Search-Range" 530 | Write-Host " `$my_obj_ref = IB-Select-Range `$my_results" 531 | write-host " `$my_range = IB-Get-Range `$my_obj_ref" 532 | Write-Host " OR" 533 | write-host " `$my_range = IB-Get-Object `$my_obj_ref []" 534 | write-host " IB-Write-Data `$my_range" 535 | Write-Host "" 536 | Write-Host "Pipelining" 537 | Write-Host " IB-Search-Range 192.168 | IB-Select-Range | IB-Get-Range | IB-Write-Data" 538 | Write-Host "" 539 | Write-Host "Use the following to see all available Infoblox functions" 540 | Write-Host " Get-ChildItem function:\IB-* | Sort-Object" 541 | write-host "" 542 | } 543 | 544 | function script:IB-Update-Object { 545 | Param ( 546 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 547 | [hashtable]$record 548 | ) 549 | 550 | BEGIN { 551 | [array]$results = @() 552 | } 553 | 554 | PROCESS { 555 | # Get the ref of the object to update 556 | $_ref = $record.Item("_ref") 557 | Write-Verbose "[update-object] $_ref" 558 | 559 | # Prepare the data 560 | $json = $record | IB-ConvertTo-JSON 561 | Write-Debug "[DEBUG] $json" 562 | 563 | # Prepare the URI 564 | $uri = "$ib_uri_base/$_ref" 565 | Write-Debug "[DEBUG] $uri" 566 | 567 | # Send the update 568 | try { 569 | $result_ref = Invoke-WebRequest -Uri $uri -ContentType application/json -Method Put -WebSession $ib_session -Body ([System.Text.Encoding]::UTF8.GetBytes($json)) 570 | } catch { 571 | Write-Host "[ERROR-exception] $_.Exception" 572 | Write-Host "[ERROR-uri] $uri" 573 | Write-Host "[ERROR-details] $_.ErrorDetails" 574 | } 575 | 576 | if ($result_ref) { 577 | [string]$rec_ref = $( IB-ConvertFrom-JSON $result_ref ) 578 | [hashtable]$hash_obj = @{ "_ref" = $rec_ref } 579 | $results += $hash_obj 580 | } 581 | } 582 | 583 | END { 584 | return $results 585 | } 586 | } 587 | 588 | 589 | ######################################## 590 | # 591 | # Infoblox helper FUNCTIONS 592 | # 593 | ######################################## 594 | 595 | function script:IB-Add-EA-to-Object { 596 | <# 597 | .SYNOPSIS 598 | This only adds the value to the in-memory object. You still need to commit the change. 599 | .NOTES 600 | There is a display issue that doesn't show the data properly after adding values. To get the display to update, convert the record TO JSON and then back. The original object is modified. 601 | #> 602 | Param ( 603 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 604 | [hashtable]$record, 605 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 606 | [string]$attribute, 607 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 608 | [string]$value 609 | ) 610 | 611 | BEGIN { } 612 | 613 | PROCESS { 614 | Write-Verbose "[add-ea] $( $record._ref ), $attribute = $value" 615 | Write-Debug "[add-ea] object = $( $record._ref )" 616 | Write-Debug "[add-ea] attribute = $attribute" 617 | Write-Debug "[add-ea] value = $value" 618 | 619 | $new_ea = @{ "value" = $value } 620 | 621 | if ($record.ContainsKey("extattrs")) { 622 | $record.extattrs.Add($attribute, $new_ea) 623 | } else { 624 | $record.Add("extattrs", $new_ea) 625 | } 626 | 627 | } 628 | 629 | END { 630 | return 631 | } 632 | } 633 | 634 | function script:IB-Get-Network { 635 | Param ( 636 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] 637 | [string]$_ref 638 | ) 639 | 640 | BEGIN { 641 | [hashtable[]]$data_array = $null 642 | } 643 | 644 | PROCESS { 645 | Write-Verbose "[get-member] $_ref" 646 | # Specify the extra fields to return 647 | $return_fields = "comment,extattrs,members" 648 | 649 | # Get the data being requested 650 | $local_results = IB-Get-Object -_ref $_ref -_return_fields $return_fields 651 | 652 | # Add the data to our array 653 | $data_array += $local_results 654 | } 655 | 656 | END { 657 | return $data_array 658 | } 659 | } 660 | 661 | function script:IB-Get-Range { 662 | Param ( 663 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] 664 | [string]$_ref 665 | ) 666 | 667 | BEGIN { 668 | [hashtable[]]$data_array = $null 669 | } 670 | 671 | PROCESS { 672 | Write-Verbose "[get-range] $_ref" 673 | # Specify the extra fields to return 674 | $return_fields = "comment,name,extattrs,member" 675 | 676 | # Get the data being requested 677 | $local_results = IB-Get-Object -_ref $_ref -_return_fields $return_fields 678 | 679 | # Add the data to our array 680 | $data_array += $local_results 681 | } 682 | 683 | END { 684 | return $data_array 685 | } 686 | } 687 | 688 | function script:IB-Range-Member-Action { 689 | <# 690 | .SYNOPSIS 691 | This only adds the value to the in-memory object. You still need to commit the change. 692 | .NOTES 693 | There is a display issue that doesn't show the data properly after adding values. To get the display to update, convert the record TO JSON and then back. The original object is modified. 694 | #> 695 | Param ( 696 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 697 | [hashtable]$record, 698 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 699 | [string]$member, 700 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 701 | [ValidateSet("Add","Delete")] 702 | [string]$action 703 | ) 704 | 705 | BEGIN { } 706 | 707 | PROCESS { 708 | Write-Verbose "[range-member-action] $( $record._ref ), $member, $action" 709 | Write-Debug "[range-member-action] object = $( $record._ref )" 710 | Write-Debug "[range-member-action] member = $member" 711 | Write-Debug "[range-member-action] action = $action" 712 | 713 | # We could save a couple of lines but let's keep this simple to understand 714 | # We may also need this structure for more work later 715 | switch ($action) { 716 | "Add" { 717 | $new_member_record = @{ 718 | "_struct" = "dhcpmember"; 719 | "name" = $member 720 | } 721 | 722 | if ($record.ContainsKey("member")) { 723 | $record.Remove("member") 724 | } 725 | $record.Add("member", $new_member_record) 726 | 727 | } 728 | "Delete" { 729 | if ($record.ContainsKey("member")) { 730 | $record.Remove("member") 731 | } 732 | } 733 | } 734 | } 735 | 736 | END { 737 | return 738 | } 739 | } 740 | 741 | function script:IB-Search-Network { 742 | Param ( 743 | [Parameter(Mandatory=$true,Position=0)] 744 | [string]$search_string = $null 745 | ) 746 | 747 | BEGIN { } 748 | 749 | PROCESS { } 750 | 751 | END { 752 | Write-Verbose "[search-network] $search_string" 753 | $local_results = IB-Search -search_string $search_string -objtype network 754 | 755 | return $local_results 756 | } 757 | } 758 | 759 | function script:IB-Search-Range { 760 | Param ( 761 | [Parameter(Mandatory=$true,Position=0)] 762 | [string]$search_string = $null 763 | ) 764 | 765 | BEGIN { } 766 | 767 | PROCESS { } 768 | 769 | END { 770 | Write-Verbose "[search-range] $search_string" 771 | $local_results = IB-Search -search_string $search_string -objtype range 772 | 773 | return $local_results 774 | } 775 | } 776 | 777 | function script:IB-Select-Range { 778 | Param ( 779 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 780 | [hashtable]$range_results, 781 | [Parameter(Mandatory=$false)] 782 | [switch]$ref_only 783 | ) 784 | 785 | BEGIN { 786 | if (!$ib_session) { 787 | Write-Host "[ERROR] Try creating a session first. 'IB-Create-Session'" 788 | return $false 789 | } 790 | 791 | [array]$range_array = $() 792 | [int]$counter = 0 793 | Write-Verbose '[select-range] begin' 794 | } 795 | 796 | PROCESS { 797 | # Print the current record 798 | $range_results | foreach { $counter++; write-host " [$counter] $($_.network), $($_.start_addr)-$($_.end_addr), $($_.network_view), $($_.comment)" } 799 | 800 | # Store the record so we can return only the one we want later 801 | $range_array += $range_results 802 | } 803 | 804 | END { 805 | Write-Debug "[DEBUG] Select-Range: number of options: $counter" 806 | 807 | switch ($counter) { 808 | 0 { return $false } 809 | 1 { return $range_results } 810 | default { 811 | Write-Host "Multiple matches found: Please select an option from below" 812 | [int]$choice = IB-Get-Input-Choice( $counter ) 813 | 814 | # Then return the indexed _ref for the appropriate answer 815 | if ($choice) { 816 | if ($ref_only) { 817 | return $( $range_array[$( $choice-1 )]._ref ) 818 | } else { 819 | return $( $range_array[$( $choice-1 )] ) 820 | } 821 | } 822 | } 823 | } 824 | 825 | return $false 826 | } 827 | } 828 | 829 | function script:IB-Show-Connection-Details { 830 | #Get-ChildItem variable:ib_* | foreach { write-host "$($_.Name) = $($_.Value)" } 831 | Get-ChildItem variable:ib* -Exclude ib_session 832 | 833 | #Get-ChildItem function:IB-* | Sort-Object 834 | } 835 | 836 | 837 | ######################################## 838 | # 839 | # MAIN 840 | # 841 | ######################################## 842 | 843 | 844 | ######################################## 845 | # Show examples of what someone should do now 846 | # 847 | IB-Ignore-Self-Signed-Certs 848 | 849 | IB-Show-Examples 850 | 851 | # Clear-Variable ibvar_* 852 | <# 853 | if (ib-create-session -wapi_ver v1.2.1) { 854 | Write-Host "Create a single network..." 855 | [hashtable]$ibvar_new0 = @{ "network" = "12.0.0.0/24"; "comment" = "net0" } 856 | $ibvar_add_one = IB-Create-Object $ibvar_new0 -obj_type network 857 | 858 | Write-host "Create multiple newtorks..." 859 | [hashtable]$ibvar_new1 = @{ "network" = "12.0.1.0/24"; "comment" = "net1" } 860 | [hashtable]$ibvar_new2 = @{ "network" = "12.0.2.0/24"; "comment" = "net2" } 861 | [array]$ibvar_new_rec_array = @() 862 | $ibvar_new_rec_array += $ibvar_new1 863 | $ibvar_new_rec_array += $ibvar_new2 864 | $ibvar_add_multiple = $ibvar_new_rec_array | IB-Create-Object -obj_type network 865 | IB-Write-Data $ibvar_add_multiple[0] 866 | 867 | Write-Host "Create network with an EA..." 868 | [hashtable]$ibvar_new3 = @{ "network" = "12.0.3.0/24"; "comment" = "net3" } 869 | #IB-Add-EA-to-Object $ibvar_new3 -attribute "Site" -value "Test Site" 870 | IB-Create-Object $ibvar_new3 -obj_type network 871 | 872 | Write-Host "Search for created networks..." 873 | $ibvar_net12_search = IB-Search-Network 12.0 874 | $ibvar_net12_objs = $ibvar_net12_search | IB-Get-Object 875 | $ibvar_net12_objs | IB-Write-Data 876 | 877 | Write-Host "Delete a single network..." 878 | IB-Delete-Object $ibvar_net12_objs[0] -force 879 | $ibvar_net12_search = IB-Search-Network 12.0 880 | $ibvar_net12_objs = $ibvar_net12_search | IB-Get-Object 881 | $ibvar_net12_objs | IB-Write-Data 882 | 883 | Write-Host "Perform a simple update..." 884 | $ibvar_net12_search = IB-Search-Network 12.0.1.0 885 | $ibvar_net12_objs = $ibvar_net12_search | IB-Get-Object 886 | $ibvar_net12_objs.comment 887 | $ibvar_net12_objs[0].comment = "index-0 changed" 888 | #IB-Update-Object $ibvar_net12_objs[0] 889 | 890 | Write-Host "Change the comments on several objects and update them..." 891 | $ibvar_net12_objs.comment 892 | $ibvar_net12_objs | foreach { $_.comment = "multi-update" } 893 | $ibvar_net12_objs.comment 894 | #$ibvar_net12_objs | IB-Update-Object 895 | 896 | 897 | Write-Host "Create several ranges..." 898 | $members = ib-search -objtype member -search_string . 899 | $dhcp_member = $members[0].host_name 900 | 901 | [hashtable]$ibvar_new_range1 = @{ 902 | #"network" = "12.0.1.0/24"; 903 | "name" = "range1.1"; 904 | "comment" = "new range 1"; 905 | "start_addr" = "12.0.1.101"; 906 | "end_addr" = "12.0.1.150"; 907 | #"server_association_type" = "MEMBER"; 908 | #"member" = "$( $dhcp_member )" 909 | } 910 | 911 | [hashtable]$ibvar_new_range2 = @{ 912 | #"network" = "12.0.1.0/24"; 913 | "name" = "range1.2"; 914 | "comment" = "new range 2"; 915 | "start_addr" = "12.0.1.201"; 916 | "end_addr" = "12.0.1.250"; 917 | #"server_association_type" = "MEMBER"; 918 | #"member" = "$( $dhcp_member )" 919 | } 920 | 921 | [hashtable]$ibvar_new_range3 = @{ 922 | #"network" = "12.0.2.0/24"; 923 | "name" = "range2"; 924 | "comment" = "new range 3"; 925 | "start_addr" = "12.0.2.101"; 926 | "end_addr" = "12.0.2.150"; 927 | #"server_association_type" = "MEMBER"; 928 | #"member" = "$( $dhcp_member )" 929 | } 930 | 931 | [array]$ibvar_new_range_array = @() 932 | $ibvar_new_range_array += $ibvar_new_range1 933 | $ibvar_new_range_array += $ibvar_new_range2 934 | $ibvar_new_range_array += $ibvar_new_range3 935 | $ibvar_add_multiple = $ibvar_new_range_array | IB-Create-Object -obj_type range 936 | 937 | Write-Host "Search for a single range match..." 938 | $ibvar_r = ib-search-range 12.0.1 939 | $ibvar_r_details = $ibvar_r | ib-get-range 940 | 941 | Write-Host "Search for multiple ranges in a network..." 942 | $ibvar_w = IB-Search-Range 12.0 943 | $ibvar_w_details = $ibvar_w | IB-Get-Range 944 | 945 | Write-Host "Clean up created objects..." 946 | #ib-search-range 12.0 | IB-Delete-Object -force 947 | 948 | # Debugging 949 | #IB-Search 192.168 range | IB-Get-Range | IB-Write-Data 950 | IB-Search 192.168 range | IB-Get-Range | IB-Range-Member-Action -action Delete -member gm.lab.local 951 | IB-Search 192.168 range | IB-Get-Range | IB-Range-Member-Action -action Add -member gm.lab.local 952 | IB-Search-Network 192.168 | IB-Get-Network | IB-Write-Data 953 | } 954 | #> --------------------------------------------------------------------------------