├── .gitattributes ├── .gitignore ├── AddToXML.ps1 ├── GPWmiFilter.psm1 ├── MergeXml.psd1 ├── MergeXml.psm1 ├── VIADeployModule.psm1 ├── VIAHypervModule.psm1 ├── VIANicModule.psm1 ├── VIARacAdm.psm1 ├── VIASCVMMModule.psm1 ├── VIAStorageModule.psm1 ├── VIAUtilityModule.psm1 └── VIAXMLUtility.psm1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.md text 7 | *.gitattributes text 8 | 9 | # Declare files that will always have CRLF line endings on checkout. 10 | *.ps1 text eol=crlf 11 | *.psm1 text eol=crlf 12 | *.psd1 text eol=crlf 13 | *.psc1 text eol=crlf 14 | *.ps1xml text eol=crlf 15 | *.clixml text eol=crlf 16 | *.xml text eol=crlf 17 | *.txt text eol=crlf 18 | 19 | # Denote all files that are truly binary and should not be mergeable. 20 | *.dll binary 21 | *.exe binary 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | desktop.ini 3 | *.log 4 | *.bak 5 | *.cache 6 | *.sublime-* 7 | VIADemoModule.psm1 8 | VIAIloAdm.psm1 9 | -------------------------------------------------------------------------------- /AddToXML.ps1: -------------------------------------------------------------------------------- 1 | # this is where the document will be saved: 2 | $Path = "C:\Test\inventory.xml" 3 | 4 | # get an XMLTextWriter to create the XML 5 | $XmlWriter = New-Object System.XMl.XmlTextWriter($Path,$Null) 6 | 7 | # choose a pretty formatting: 8 | $xmlWriter.Formatting = 'Indented' 9 | $xmlWriter.Indentation = 1 10 | $XmlWriter.IndentChar = "`t" 11 | 12 | # write the header 13 | $xmlWriter.WriteStartDocument() 14 | 15 | # set XSL statements 16 | $xmlWriter.WriteProcessingInstruction("xml-stylesheet", "type='text/xsl' href='style.xsl'") 17 | 18 | # create root element "machines" and add some attributes to it 19 | $XmlWriter.WriteComment('List of machines') 20 | $xmlWriter.WriteStartElement('Machines') 21 | $XmlWriter.WriteAttributeString('current', $true) 22 | $XmlWriter.WriteAttributeString('manager', 'Tobias') 23 | 24 | # add a couple of random entries 25 | for($x=1; $x -le 10; $x++) 26 | { 27 | $server = 'Server{0:0000}' -f $x 28 | $ip = '{0}.{1}.{2}.{3}' -f (0..256 | Get-Random -Count 4) 29 | 30 | $guid = [System.GUID]::NewGuid().ToString() 31 | 32 | # each data set is called "machine", add a random attribute to it: 33 | $XmlWriter.WriteComment("$x. machine details") 34 | $xmlWriter.WriteStartElement('Machine') 35 | $XmlWriter.WriteAttributeString('test', (Get-Random)) 36 | 37 | # add three pieces of information: 38 | $xmlWriter.WriteElementString('Name',$server) 39 | $xmlWriter.WriteElementString('IP',$ip) 40 | $xmlWriter.WriteElementString('GUID',$guid) 41 | 42 | # add a node with attributes and content: 43 | $XmlWriter.WriteStartElement('Information') 44 | $XmlWriter.WriteAttributeString('info1', 'some info') 45 | $XmlWriter.WriteAttributeString('info2', 'more info') 46 | $XmlWriter.WriteRaw('RawContent') 47 | $xmlWriter.WriteEndElement() 48 | 49 | # add a node with CDATA section: 50 | $XmlWriter.WriteStartElement('CodeSegment') 51 | $XmlWriter.WriteAttributeString('info3', 'another attribute') 52 | $XmlWriter.WriteCData('this is untouched code and can contain special characters /\@<>') 53 | $xmlWriter.WriteEndElement() 54 | 55 | # close the "machine" node: 56 | $xmlWriter.WriteEndElement() 57 | } 58 | 59 | # close the "machines" node: 60 | $xmlWriter.WriteEndElement() 61 | 62 | # finalize the document: 63 | $xmlWriter.WriteEndDocument() 64 | $xmlWriter.Flush() 65 | $xmlWriter.Close() 66 | 67 | notepad $path 68 | -------------------------------------------------------------------------------- /GPWmiFilter.psm1: -------------------------------------------------------------------------------- 1 | # Copyright (C)2012 Microsoft Corporation. All rights reserved. 2 | # For personal use only. Provided AS IS and WITH ALL FAULTS. 3 | # 4 | # GPWmiFilter module v1.0.1 5 | # 6 | # binyi@microsoft.com 7 | 8 | Import-Module ActiveDirectory 9 | Import-Module GroupPolicy 10 | 11 | function New-GPWmiFilter { 12 | <# 13 | .SYNOPSIS 14 | Create a new WMI filter for Group Policy with given name, WQL query and description. 15 | 16 | .DESCRIPTION 17 | The New-GPWmiFilter function create an AD object for WMI filter with specific name, WQL query expressions and description. 18 | With -PassThru switch, it output the WMIFilter instance which can be assigned to GPO.WMIFilter property. 19 | 20 | .PARAMETER Name 21 | The name of new WMI filter. 22 | 23 | .PARAMETER Expression 24 | The expression(s) of WQL query in new WMI filter. Pass an array to this parameter if multiple WQL queries applied. 25 | 26 | .PARAMETER Description 27 | The description text of the WMI filter (optional). 28 | 29 | .PARAMETER PassThru 30 | Output the new WMI filter instance with this switch. 31 | 32 | .EXAMPLE 33 | New-GPWmiFilter -Name 'Virtual Machines' -Expression 'SELECT * FROM Win32_ComputerSystem WHERE Model = "Virtual Machine"' -Description 'Only apply on virtual machines' 34 | 35 | Create a WMI filter to apply GPO only on virtual machines 36 | 37 | .EXAMPLE 38 | $filter = New-GPWmiFilter -Name 'Workstation 32-bit' -Expression 'SELECT * FROM WIN32_OperatingSystem WHERE ProductType=1', 'SELECT * FROM Win32_Processor WHERE AddressWidth = "32"' -PassThru 39 | $gpo = New-GPO -Name "Test GPO" 40 | $gpo.WmiFilter = $filter 41 | 42 | Create a WMI filter for 32-bit work station and link it to a new GPO named "Test GPO". 43 | 44 | .NOTES 45 | Domain administrator priviledge is required for executing this cmdlet 46 | 47 | #> 48 | [CmdletBinding()] 49 | Param 50 | ( 51 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] 52 | [ValidateNotNull()] 53 | [string] $Name, 54 | 55 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] 56 | [ValidateNotNull()] 57 | [string[]] $Expression, 58 | 59 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=2)] 60 | [string] $Description, 61 | 62 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] 63 | [switch] $PassThru 64 | ) 65 | if ($Expression.Count -lt 1) 66 | { 67 | Write-Error "At least one Expression Method is required to create a WMI Filter." 68 | return 69 | } 70 | 71 | $Guid = [System.Guid]::NewGuid() 72 | $defaultNamingContext = (Get-ADRootDSE).DefaultNamingContext 73 | $msWMIAuthor = Get-Author 74 | $msWMICreationDate = (Get-Date).ToUniversalTime().ToString("yyyyMMddhhmmss.ffffff-000") 75 | $WMIGUID = "{$Guid}" 76 | $WMIDistinguishedName = "CN=$WMIGUID,CN=SOM,CN=WMIPolicy,CN=System,$defaultNamingContext" 77 | $msWMIParm1 = "$Description " 78 | $msWMIParm2 = $Expression.Count.ToString() + ";" 79 | $Expression | ForEach-Object { 80 | $msWMIParm2 += "3;10;" + $_.Length + ";WQL;root\CIMv2;" + $_ + ";" 81 | } 82 | 83 | $Attr = @{ 84 | "msWMI-Name" = $Name; 85 | "msWMI-Parm1" = $msWMIParm1; 86 | "msWMI-Parm2" = $msWMIParm2; 87 | "msWMI-Author" = $msWMIAuthor; 88 | "msWMI-ID"= $WMIGUID; 89 | "instanceType" = 4; 90 | "showInAdvancedViewOnly" = "TRUE"; 91 | "distinguishedname" = $WMIDistinguishedName; 92 | "msWMI-ChangeDate" = $msWMICreationDate; 93 | "msWMI-CreationDate" = $msWMICreationDate 94 | } 95 | 96 | $WMIPath = ("CN=SOM,CN=WMIPolicy,CN=System,$defaultNamingContext") 97 | 98 | Enable-ADSystemOnlyChange 99 | 100 | $ADObject = New-ADObject -Name $WMIGUID -Type "msWMI-Som" -Path $WMIPath -OtherAttributes $Attr -PassThru 101 | 102 | if ($PassThru) 103 | { 104 | ConvertTo-WmiFilter $ADObject | Write-Output 105 | } 106 | } 107 | 108 | function Get-GPWmiFilter { 109 | <# 110 | .SYNOPSIS 111 | Get a WMI filter in current domain 112 | 113 | .DESCRIPTION 114 | The Get-GPWmiFilter function query WMI filter(s) in current domain with specific name or GUID. 115 | 116 | .PARAMETER Guid 117 | The guid of WMI filter you want to query out. 118 | 119 | .PARAMETER Name 120 | The name of WMI filter you want to query out. 121 | 122 | .PARAMETER All 123 | Query all WMI filters in current domain With this switch. 124 | 125 | .EXAMPLE 126 | Get-GPWmiFilter -Name 'Virtual Machines' 127 | 128 | Get WMI filter(s) with the name 'Virtual Machines' 129 | 130 | .EXAMPLE 131 | Get-GPWmiFilter -All 132 | 133 | Get all WMI filters in current domain 134 | 135 | #> 136 | Param 137 | ( 138 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByGUID")] 139 | [ValidateNotNull()] 140 | [Guid[]] $Guid, 141 | 142 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByName")] 143 | [ValidateNotNull()] 144 | [string[]] $Name, 145 | 146 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="GetAll")] 147 | [ValidateNotNull()] 148 | [switch] $All 149 | ) 150 | if ($Guid) 151 | { 152 | $ADObject = Get-WMIFilterInADObject -Guid $Guid 153 | } 154 | elseif ($Name) 155 | { 156 | $ADObject = Get-WMIFilterInADObject -Name $Name 157 | } 158 | elseif ($All) 159 | { 160 | $ADObject = Get-WMIFilterInADObject -All 161 | } 162 | ConvertTo-WmiFilter $ADObject | Write-Output 163 | } 164 | 165 | function Remove-GPWmiFilter { 166 | <# 167 | .SYNOPSIS 168 | Remove a WMI filter from current domain 169 | 170 | .DESCRIPTION 171 | The Remove-GPWmiFilter function remove WMI filter(s) in current domain with specific name or GUID. 172 | 173 | .PARAMETER Guid 174 | The guid of WMI filter you want to remove. 175 | 176 | .PARAMETER Name 177 | The name of WMI filter you want to remove. 178 | 179 | .EXAMPLE 180 | Remove-GPWmiFilter -Name 'Virtual Machines' 181 | 182 | Remove the WMI filter with name 'Virtual Machines' 183 | 184 | .NOTES 185 | Domain administrator priviledge is required for executing this cmdlet 186 | 187 | #> 188 | [CmdletBinding(DefaultParametersetName="ByGUID")] 189 | Param 190 | ( 191 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByGUID")] 192 | [ValidateNotNull()] 193 | [Guid[]] $Guid, 194 | 195 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByName")] 196 | [ValidateNotNull()] 197 | [string[]] $Name 198 | ) 199 | if ($Guid) 200 | { 201 | $ADObject = Get-WMIFilterInADObject -Guid $Guid 202 | } 203 | elseif ($Name) 204 | { 205 | $ADObject = Get-WMIFilterInADObject -Name $Name 206 | } 207 | $ADObject | ForEach-Object { 208 | if ($_.DistinguishedName) 209 | { 210 | Remove-ADObject $_ -Confirm:$false 211 | } 212 | } 213 | } 214 | 215 | function Set-GPWmiFilter { 216 | <# 217 | .SYNOPSIS 218 | Get a WMI filter in current domain and update the content of it 219 | 220 | .DESCRIPTION 221 | The Set-GPWmiFilter function query WMI filter(s) in current domain with specific name or GUID and then update the content of it. 222 | 223 | .PARAMETER Guid 224 | The guid of WMI filter you want to query out. 225 | 226 | .PARAMETER Name 227 | The name of WMI filter you want to query out. 228 | 229 | .PARAMETER Expression 230 | The expression(s) of WQL query in new WMI filter. Pass an array to this parameter if multiple WQL queries applied. 231 | 232 | .PARAMETER Description 233 | The description text of the WMI filter (optional). 234 | 235 | .PARAMETER PassThru 236 | Output the updated WMI filter instance with this switch. 237 | 238 | .EXAMPLE 239 | Set-GPWmiFilter -Name 'Workstations' -Expression 'SELECT * FROM Win32_OperatingSystem WHERE ProductType = "1"' 240 | 241 | Set WMI filter named with "Workstations" to specific WQL query 242 | 243 | .NOTES 244 | Domain administrator priviledge is required for executing this cmdlet. 245 | Either -Expression or -Description should be assigned when executing. 246 | 247 | #> 248 | Param 249 | ( 250 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByGUID")] 251 | [ValidateNotNull()] 252 | [Guid[]] $Guid, 253 | 254 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByName")] 255 | [ValidateNotNull()] 256 | [string[]] $Name, 257 | 258 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=1)] 259 | [ValidateNotNull()] 260 | [string[]] $Expression, 261 | 262 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=2)] 263 | [string] $Description, 264 | 265 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] 266 | [switch] $PassThru 267 | 268 | ) 269 | if ($Guid) 270 | { 271 | $ADObject = Get-WMIFilterInADObject -Guid $Guid 272 | } 273 | elseif ($Name) 274 | { 275 | $ADObject = Get-WMIFilterInADObject -Name $Name 276 | } 277 | $msWMIAuthor = Get-Author 278 | $msWMIChangeDate = (Get-Date).ToUniversalTime().ToString("yyyyMMddhhmmss.ffffff-000") 279 | $Attr = @{ 280 | "msWMI-Author" = $msWMIAuthor; 281 | "msWMI-ChangeDate" = $msWMIChangeDate; 282 | } 283 | if ($Expression) 284 | { 285 | $msWMIParm2 = $Expression.Count.ToString() + ";" 286 | $Expression | ForEach-Object { 287 | $msWMIParm2 += "3;10;" + $_.Length + ";WQL;root\CIMv2;" + $_ + ";" 288 | } 289 | $Attr.Add("msWMI-Parm2", $msWMIParm2); 290 | } 291 | elseif ($Description) 292 | { 293 | $msWMIParm1 = $Description + " " 294 | $Attr.Add("msWMI-Parm2", $msWMIParm2); 295 | } 296 | else 297 | { 298 | Write-Warning "No content need to be set. Please set either Expression or Description." 299 | return 300 | } 301 | 302 | Enable-ADSystemOnlyChange 303 | 304 | $ADObject | ForEach-Object { 305 | if ($_.DistinguishedName) 306 | { 307 | Set-ADObject -Identity $_ -Replace $Attr 308 | if ($PassThru) 309 | { 310 | ConvertTo-WmiFilter $ADObject | Write-Output 311 | } 312 | } 313 | } 314 | } 315 | 316 | function Rename-GPWmiFilter { 317 | <# 318 | .SYNOPSIS 319 | Get a WMI filter in current domain and rename it 320 | 321 | .DESCRIPTION 322 | The Rename-GPWmiFilter function query WMI filter in current domain with specific name or GUID and then change it to a new name. 323 | 324 | .PARAMETER Guid 325 | The guid of WMI filter you want to query out. 326 | 327 | .PARAMETER Name 328 | The name of WMI filter you want to query out. 329 | 330 | .PARAMETER TargetName 331 | The new name of WMI filter. 332 | 333 | .PARAMETER PassThru 334 | Output the renamed WMI filter instance with this switch. 335 | 336 | .EXAMPLE 337 | Rename-GPWmiFilter -Name 'Workstations' -TargetName 'Client Machines' 338 | 339 | Rename WMI filter "Workstations" to "Client Machines" 340 | 341 | .NOTES 342 | Domain administrator priviledge is required for executing this cmdlet. 343 | 344 | #> 345 | Param 346 | ( 347 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByGUID")] 348 | [ValidateNotNull()] 349 | [Guid[]] $Guid, 350 | 351 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByName")] 352 | [ValidateNotNull()] 353 | [string[]] $Name, 354 | 355 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] 356 | [ValidateNotNull()] 357 | [string] $TargetName, 358 | 359 | [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] 360 | [switch] $PassThru 361 | ) 362 | if ($Guid) 363 | { 364 | $ADObject = Get-WMIFilterInADObject -Guid $Guid 365 | } 366 | elseif ($Name) 367 | { 368 | $ADObject = Get-WMIFilterInADObject -Name $Name 369 | } 370 | 371 | if (!$Name) 372 | { 373 | $Name = $ADObject."msWMI-Name" 374 | } 375 | if ($TargetName -eq $Name) 376 | { 377 | return 378 | } 379 | 380 | $msWMIAuthor = Get-Author 381 | $msWMIChangeDate = (Get-Date).ToUniversalTime().ToString("yyyyMMddhhmmss.ffffff-000") 382 | $Attr = @{ 383 | "msWMI-Author" = $msWMIAuthor; 384 | "msWMI-ChangeDate" = $msWMIChangeDate; 385 | "msWMI-Name" = $TargetName; 386 | } 387 | 388 | Enable-ADSystemOnlyChange 389 | 390 | $ADObject | ForEach-Object { 391 | if ($_.DistinguishedName) 392 | { 393 | Set-ADObject -Identity $_ -Replace $Attr 394 | if ($PassThru) 395 | { 396 | ConvertTo-WmiFilter $ADObject | Write-Output 397 | } 398 | } 399 | } 400 | } 401 | 402 | ####################################################################### Helper functions ##################################################################### 403 | 404 | function ConvertTo-WmiFilter([Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject) 405 | { 406 | $gpDomain = New-Object -Type Microsoft.GroupPolicy.GPDomain 407 | $ADObject | ForEach-Object { 408 | $path = 'MSFT_SomFilter.Domain="' + $gpDomain.DomainName + '",ID="' + $_.Name + '"' 409 | try 410 | { 411 | $filter = $gpDomain.GetWmiFilter($path) 412 | } 413 | catch { } 414 | if ($filter) 415 | { 416 | [Guid]$Guid = $_.Name.Substring(1, $_.Name.Length - 2) 417 | $filter | Add-Member -MemberType NoteProperty -Name Guid -Value $Guid -PassThru | Add-Member -MemberType NoteProperty -Name Content -Value $_."msWMI-Parm2" -PassThru | Write-Output 418 | } 419 | } 420 | } 421 | 422 | function ConvertTo-ADObject([Microsoft.GroupPolicy.WmiFilter[]] $WmiFilter) 423 | { 424 | $wmiFilterAttr = "msWMI-Name", "msWMI-Parm1", "msWMI-Parm2", "msWMI-Author", "msWMI-ID" 425 | $WmiFilter | ForEach-Object { 426 | $match = $_.Path | Select-String -Pattern 'ID=\"\{(?[\-|a-f|0-9]+)\}\"' | Select-Object -Expand Matches | ForEach-Object { $_.Groups[1] } 427 | [Guid]$Guid = $match.Value 428 | $ldapFilter = "(&(objectClass=msWMI-Som)(Name={$Guid}))" 429 | Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr | Write-Output 430 | } 431 | } 432 | 433 | function Enable-ADSystemOnlyChange([switch] $disable) 434 | { 435 | $valueData = 1 436 | if ($disable) 437 | { 438 | $valueData = 0 439 | } 440 | $key = Get-Item HKLM:\System\CurrentControlSet\Services\NTDS\Parameters -ErrorAction SilentlyContinue 441 | if (!$key) { 442 | New-Item HKLM:\System\CurrentControlSet\Services\NTDS\Parameters -ItemType RegistryKey | Out-Null 443 | } 444 | $kval = Get-ItemProperty HKLM:\System\CurrentControlSet\Services\NTDS\Parameters -Name "Allow System Only Change" -ErrorAction SilentlyContinue 445 | if (!$kval) { 446 | New-ItemProperty HKLM:\System\CurrentControlSet\Services\NTDS\Parameters -Name "Allow System Only Change" -Value $valueData -PropertyType DWORD | Out-Null 447 | } else { 448 | Set-ItemProperty HKLM:\System\CurrentControlSet\Services\NTDS\Parameters -Name "Allow System Only Change" -Value $valueData | Out-Null 449 | } 450 | } 451 | 452 | function Get-WMIFilterInADObject { 453 | Param( 454 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByGUID")] 455 | [ValidateNotNull()] 456 | [Guid[]] $Guid, 457 | 458 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="ByName")] 459 | [ValidateNotNull()] 460 | [string[]] $Name, 461 | 462 | [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName="GetAll")] 463 | [ValidateNotNull()] 464 | [switch] $All 465 | 466 | ) 467 | $wmiFilterAttr = "msWMI-Name", "msWMI-Parm1", "msWMI-Parm2", "msWMI-Author", "msWMI-ID" 468 | if ($Guid) 469 | { 470 | $Guid | ForEach-Object { 471 | $ldapFilter = "(&(objectClass=msWMI-Som)(Name={$_}))" 472 | Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr | Write-Output 473 | } 474 | } 475 | elseif ($Name) 476 | { 477 | $Name | ForEach-Object { 478 | $ldapFilter = "(&(objectClass=msWMI-Som)(msWMI-Name=$_))" 479 | Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr | Write-Output 480 | } 481 | } 482 | elseif ($All) 483 | { 484 | $ldapFilter = "(objectClass=msWMI-Som)" 485 | Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr | Write-Output 486 | } 487 | } 488 | 489 | function Get-Author 490 | { 491 | $author = (Get-ADUser $env:USERNAME).UserPrincipalName 492 | if (!$author) 493 | { 494 | $author = (Get-ADUser $env:USERNAME).Name 495 | } 496 | if (!$author) 497 | { 498 | $author = $env:USERNAME 499 | } 500 | return $author 501 | } 502 | 503 | 504 | Export-ModuleMember -Function New-GPWmiFilter, Get-GPWmiFilter, Remove-GPWmiFilter, Set-GPWmiFilter, Rename-GPWmiFilter -------------------------------------------------------------------------------- /MergeXml.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeploymentBunny/Functions/5e8140ad8bde1882f113aa89fe712ed0342f7b98/MergeXml.psd1 -------------------------------------------------------------------------------- /MergeXml.psm1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeploymentBunny/Functions/5e8140ad8bde1882f113aa89fe712ed0342f7b98/MergeXml.psm1 -------------------------------------------------------------------------------- /VIADeployModule.psm1: -------------------------------------------------------------------------------- 1 | Function New-VIAUnattendXML 2 | { 3 | <# 4 | ################################################################################## 5 | # Script name: Create-UnattendXML.ps1 6 | # Created: 2013-09-02 7 | # version: v1.0 8 | # Author: Mikael Nystrom 9 | # Homepage: http://deploymentbunny.com/ 10 | ################################################################################## 11 | 12 | ################################################################################## 13 | # Disclaimer: 14 | # ----------- 15 | # This script is provided "AS IS" with no warranties, confers no rights and 16 | # is not supported by the authors or DeploymentBunny. 17 | ################################################################################## 18 | #> 19 | [cmdletbinding(SupportsShouldProcess=$True)] 20 | Param( 21 | [parameter(mandatory=$true)] 22 | [ValidateNotNullOrEmpty()] 23 | $Computername, 24 | 25 | [parameter(mandatory=$true)] 26 | [ValidateNotNullOrEmpty()] 27 | $OSDAdapter0IPAddressList, 28 | 29 | [parameter(mandatory=$false)] 30 | [ValidateSet("Domain","Workgroup")] 31 | $DomainOrWorkGroup, 32 | 33 | [parameter(mandatory=$false)] 34 | $ProductKey = 'NONE', 35 | 36 | [parameter(mandatory=$false)] 37 | $AdminPassword = "P@ssw0rd", 38 | 39 | [parameter(mandatory=$false)] 40 | $OrgName = "ViaMonstra", 41 | 42 | [parameter(mandatory=$false)] 43 | $Fullname = "ViaMonstra", 44 | 45 | [parameter(mandatory=$false)] 46 | $TimeZoneName = "Pacific Standard Time", 47 | 48 | [parameter(mandatory=$false)] 49 | $InputLocale = "en-US", 50 | 51 | [parameter(mandatory=$false)] 52 | $SystemLocale = "en-US", 53 | 54 | [parameter(mandatory=$false)] 55 | $UILanguage = "en-US", 56 | 57 | [parameter(mandatory=$false)] 58 | $UserLocale = "en-US", 59 | 60 | [parameter(mandatory=$false)] 61 | $OSDAdapter0Gateways = "192.168.1.1", 62 | 63 | [parameter(mandatory=$false)] 64 | $OSDAdapter0DNS1 = "192.168.1.200", 65 | 66 | [parameter(mandatory=$false)] 67 | $OSDAdapter0DNS2 = "192.168.1.201", 68 | 69 | [parameter(mandatory=$false)] 70 | $OSDAdapter0SubnetMaskPrefix = "24", 71 | 72 | [parameter(mandatory=$false)] 73 | $DNSDomain = "corp.viamonstra.com", 74 | 75 | [parameter(mandatory=$false)] 76 | $DomainNetBios = "VIAMONSTRA", 77 | 78 | [parameter(mandatory=$false)] 79 | $DomainAdmin = "Administrator", 80 | 81 | [parameter(mandatory=$false)] 82 | $DomainAdminPassword = "P@ssw0rd", 83 | 84 | [parameter(mandatory=$false)] 85 | $DomainAdminDomain = "VIAMONSTRA", 86 | 87 | [parameter(mandatory=$false)] 88 | $MachineObjectOU = "NA", 89 | 90 | [parameter(mandatory=$false)] 91 | $JoinWorkgroup = "WORKGROUP", 92 | 93 | [parameter(mandatory=$false)] 94 | [ValidateSet("1","2","3")] 95 | $ProtectYourPC = "3" 96 | ) 97 | 98 | if((Test-Path -Path .\Unattend.xml) -eq $true) 99 | { 100 | Remove-Item -Path .\Unattend.xml 101 | } 102 | 103 | Write-Verbose "IP is $OSDAdapter0IPAddressList" 104 | $unattendFile = New-Item -Path "Unattend.xml" -type File 105 | Set-Content $unattendFile '' 106 | Add-Content $unattendFile '' 107 | Add-Content $unattendFile ' ' 108 | 109 | Switch ($DomainOrWorkGroup){ 110 | DOMAIN 111 | { 112 | Write-Verbose "Configure for domain mode" 113 | Add-Content $unattendFile ' ' 114 | Add-Content $unattendFile ' ' 115 | Add-Content $unattendFile ' ' 116 | Add-Content $unattendFile " $DomainAdmin" 117 | Add-Content $unattendFile " $DomainAdminDomain" 118 | Add-Content $unattendFile " $DomainAdminPassword" 119 | Add-Content $unattendFile ' ' 120 | Add-Content $unattendFile " $DNSDomain" 121 | If(!($MachineObjectOU -eq 'NA')){ 122 | Write-Verbose "OU is set to $MachineObjectOU" 123 | Add-Content $unattendFile " $MachineObjectOU" 124 | } 125 | Add-Content $unattendFile ' ' 126 | Add-Content $unattendFile ' ' 127 | } 128 | WORKGROUP 129 | { 130 | Write-Verbose "Configure unattend.xml for workgroup mode" 131 | Add-Content $unattendFile ' ' 132 | Add-Content $unattendFile ' ' 133 | Add-Content $unattendFile " $JoinWorkgroup" 134 | Add-Content $unattendFile ' ' 135 | Add-Content $unattendFile ' ' 136 | } 137 | Default 138 | { 139 | Write-Verbose "Epic Fail, exit..." 140 | Exit 141 | } 142 | } 143 | Add-Content $unattendFile ' ' 144 | Add-Content $unattendFile " $ComputerName" 145 | 146 | If($ProductKey -eq 'NONE') 147 | { 148 | Write-Verbose "No Productkey" 149 | } 150 | else 151 | { 152 | Write-Verbose "Adding Productkey $ProductKey" 153 | Add-Content $unattendFile " $ProductKey" 154 | } 155 | Add-Content $unattendFile " $OrgName" 156 | Add-Content $unattendFile " $Fullname" 157 | Add-Content $unattendFile ' true' 158 | Add-Content $unattendFile " $TimeZoneName" 159 | Add-Content $unattendFile ' ' 160 | Add-Content $unattendFile ' ' 161 | Add-Content $unattendFile " $InputLocale" 162 | Add-Content $unattendFile " $SystemLocale" 163 | Add-Content $unattendFile " $UILanguage" 164 | Add-Content $unattendFile " $UserLocale" 165 | Add-Content $unattendFile ' ' 166 | if ($OSDAdapter0IPAddressList -contains "DHCP") 167 | { 168 | Write-Verbose "IP is $OSDAdapter0IPAddressList so we prep for DHCP" 169 | } 170 | else 171 | { 172 | Write-Verbose "IP is $OSDAdapter0IPAddressList so we prep for Static IP" 173 | Add-Content $unattendFile ' ' 174 | Add-Content $unattendFile ' ' 175 | Add-Content $unattendFile ' ' 176 | Add-Content $unattendFile ' ' 177 | Add-Content $unattendFile " $OSDAdapter0DNS1" 178 | Add-Content $unattendFile " $OSDAdapter0DNS2" 179 | Add-Content $unattendFile ' ' 180 | Add-Content $unattendFile ' Ethernet' 181 | Add-Content $unattendFile ' ' 182 | Add-Content $unattendFile ' ' 183 | Add-Content $unattendFile ' ' 184 | Add-Content $unattendFile ' ' 185 | Add-Content $unattendFile ' ' 186 | Add-Content $unattendFile ' ' 187 | Add-Content $unattendFile ' ' 188 | Add-Content $unattendFile ' false' 189 | Add-Content $unattendFile ' ' 190 | Add-Content $unattendFile ' Ethernet' 191 | Add-Content $unattendFile ' ' 192 | Add-Content $unattendFile " $OSDAdapter0IPAddressList/$OSDAdapter0SubnetMaskPrefix" 193 | Add-Content $unattendFile ' ' 194 | Add-Content $unattendFile ' ' 195 | Add-Content $unattendFile ' ' 196 | Add-Content $unattendFile ' 0' 197 | Add-Content $unattendFile " $OSDAdapter0Gateways" 198 | Add-Content $unattendFile " 0.0.0.0/0" 199 | Add-Content $unattendFile ' ' 200 | Add-Content $unattendFile ' ' 201 | Add-Content $unattendFile ' ' 202 | Add-Content $unattendFile ' ' 203 | Add-Content $unattendFile ' ' 204 | } 205 | Add-Content $unattendFile ' ' 206 | Add-Content $unattendFile ' ' 207 | Add-Content $unattendFile ' ' 208 | Add-Content $unattendFile ' ' 209 | Add-Content $unattendFile ' ' 210 | Add-Content $unattendFile " $AdminPassword" 211 | Add-Content $unattendFile ' True</PlainText>' 212 | Add-Content $unattendFile ' </AdministratorPassword>' 213 | Add-Content $unattendFile ' </UserAccounts>' 214 | Add-Content $unattendFile ' <OOBE>' 215 | Add-Content $unattendFile ' <HideEULAPage>true</HideEULAPage>' 216 | Add-Content $unattendFile ' <NetworkLocation>Work</NetworkLocation>' 217 | Add-Content $unattendFile " <ProtectYourPC>$ProtectYourPC</ProtectYourPC>" 218 | Add-Content $unattendFile ' </OOBE>' 219 | Add-Content $unattendFile " <RegisteredOrganization>$Orgname</RegisteredOrganization>" 220 | Add-Content $unattendFile " <RegisteredOwner>$FullName</RegisteredOwner>" 221 | Add-Content $unattendFile " <TimeZone>$TimeZoneName</TimeZone>" 222 | Add-Content $unattendFile ' </component>' 223 | Add-Content $unattendFile ' <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 224 | Add-Content $unattendFile " <InputLocale>$InputLocale</InputLocale>" 225 | Add-Content $unattendFile " <SystemLocale>$SystemLocale</SystemLocale>" 226 | Add-Content $unattendFile " <UILanguage>$UILanguage</UILanguage>" 227 | Add-Content $unattendFile " <UserLocale>$UserLocale</UserLocale>" 228 | Add-Content $unattendFile ' </component>' 229 | Add-Content $unattendFile ' </settings>' 230 | Add-Content $unattendFile '</unattend>' 231 | Return $unattendFile 232 | } 233 | Function New-VIAUnattendXMLClient 234 | { 235 | <# 236 | ################################################################################## 237 | # Script name: Create-UnattendXML.ps1 238 | # Created: 2013-09-02 239 | # version: v1.0 240 | # Author: Mikael Nystrom 241 | # Homepage: http://deploymentbunny.com/ 242 | ################################################################################## 243 | 244 | ################################################################################## 245 | # Disclaimer: 246 | # ----------- 247 | # This script is provided "AS IS" with no warranties, confers no rights and 248 | # is not supported by the authors or DeploymentBunny. 249 | ################################################################################## 250 | #> 251 | [cmdletbinding(SupportsShouldProcess=$True)] 252 | Param( 253 | [parameter(mandatory=$true)] 254 | [ValidateNotNullOrEmpty()] 255 | $Computername, 256 | 257 | [parameter(mandatory=$true)] 258 | [ValidateNotNullOrEmpty()] 259 | $OSDAdapter0IPAddressList, 260 | 261 | [parameter(mandatory=$false)] 262 | [ValidateSet("Domain","Workgroup")] 263 | $DomainOrWorkGroup, 264 | 265 | [parameter(mandatory=$false)] 266 | $ProductKey = 'NONE', 267 | 268 | [parameter(mandatory=$false)] 269 | $AdminPassword = "P@ssw0rd", 270 | 271 | [parameter(mandatory=$false)] 272 | $OrgName = "ViaMonstra", 273 | 274 | [parameter(mandatory=$false)] 275 | $Fullname = "ViaMonstra", 276 | 277 | [parameter(mandatory=$false)] 278 | $TimeZoneName = "Pacific Standard Time", 279 | 280 | [parameter(mandatory=$false)] 281 | $InputLocale = "en-US", 282 | 283 | [parameter(mandatory=$false)] 284 | $SystemLocale = "en-US", 285 | 286 | [parameter(mandatory=$false)] 287 | $UILanguage = "en-US", 288 | 289 | [parameter(mandatory=$false)] 290 | $UserLocale = "en-US", 291 | 292 | [parameter(mandatory=$false)] 293 | $OSDAdapter0Gateways = "192.168.1.1", 294 | 295 | [parameter(mandatory=$false)] 296 | $OSDAdapter0DNS1 = "192.168.1.200", 297 | 298 | [parameter(mandatory=$false)] 299 | $OSDAdapter0DNS2 = "192.168.1.201", 300 | 301 | [parameter(mandatory=$false)] 302 | $OSDAdapter0SubnetMaskPrefix = "24", 303 | 304 | [parameter(mandatory=$false)] 305 | $DNSDomain = "corp.viamonstra.com", 306 | 307 | [parameter(mandatory=$false)] 308 | $DomainNetBios = "VIAMONSTRA", 309 | 310 | [parameter(mandatory=$false)] 311 | $DomainAdmin = "Administrator", 312 | 313 | [parameter(mandatory=$false)] 314 | $DomainAdminPassword = "P@ssw0rd", 315 | 316 | [parameter(mandatory=$false)] 317 | $DomainAdminDomain = "VIAMONSTRA", 318 | 319 | [parameter(mandatory=$false)] 320 | $MachineObjectOU = "NA", 321 | 322 | [parameter(mandatory=$false)] 323 | $JoinWorkgroup = "WORKGROUP", 324 | 325 | [parameter(mandatory=$false)] 326 | [ValidateSet("1","2","3")] 327 | $ProtectYourPC = "3" 328 | ) 329 | 330 | if((Test-Path -Path .\Unattend.xml) -eq $true) 331 | { 332 | Remove-Item -Path .\Unattend.xml 333 | } 334 | 335 | Write-Verbose "IP is $OSDAdapter0IPAddressList" 336 | $unattendFile = New-Item -Path "Unattend.xml" -type File 337 | Set-Content $unattendFile '<?xml version="1.0" encoding="utf-8"?>' 338 | Add-Content $unattendFile '<unattend xmlns="urn:schemas-microsoft-com:unattend">' 339 | Add-Content $unattendFile ' <settings pass="specialize">' 340 | 341 | Switch ($DomainOrWorkGroup){ 342 | DOMAIN 343 | { 344 | Write-Verbose "Configure for domain mode" 345 | Add-Content $unattendFile ' <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">' 346 | Add-Content $unattendFile ' <Identification>' 347 | Add-Content $unattendFile ' <Credentials>' 348 | Add-Content $unattendFile " <Username>$DomainAdmin</Username>" 349 | Add-Content $unattendFile " <Domain>$DomainAdminDomain</Domain>" 350 | Add-Content $unattendFile " <Password>$DomainAdminPassword</Password>" 351 | Add-Content $unattendFile ' </Credentials>' 352 | Add-Content $unattendFile " <JoinDomain>$DNSDomain</JoinDomain>" 353 | If(!($MachineObjectOU -eq 'NA')){ 354 | Write-Verbose "OU is set to $MachineObjectOU" 355 | Add-Content $unattendFile " <MachineObjectOU>$MachineObjectOU</MachineObjectOU>" 356 | } 357 | Add-Content $unattendFile ' </Identification>' 358 | Add-Content $unattendFile ' </component>' 359 | } 360 | WORKGROUP 361 | { 362 | Write-Verbose "Configure unattend.xml for workgroup mode" 363 | Add-Content $unattendFile ' <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">' 364 | Add-Content $unattendFile ' <Identification>' 365 | Add-Content $unattendFile " <JoinWorkgroup>$JoinWorkgroup</JoinWorkgroup>" 366 | Add-Content $unattendFile ' </Identification>' 367 | Add-Content $unattendFile ' </component>' 368 | } 369 | Default 370 | { 371 | Write-Verbose "Epic Fail, exit..." 372 | Exit 373 | } 374 | } 375 | Add-Content $unattendFile ' <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">' 376 | Add-Content $unattendFile " <ComputerName>$ComputerName</ComputerName>" 377 | 378 | If($ProductKey -eq 'NONE') 379 | { 380 | Write-Verbose "No Productkey" 381 | } 382 | else 383 | { 384 | Write-Verbose "Adding Productkey $ProductKey" 385 | Add-Content $unattendFile " <ProductKey>$ProductKey</ProductKey>" 386 | } 387 | Add-Content $unattendFile " <RegisteredOrganization>$OrgName</RegisteredOrganization>" 388 | Add-Content $unattendFile " <RegisteredOwner>$Fullname</RegisteredOwner>" 389 | Add-Content $unattendFile ' <DoNotCleanTaskBar>true</DoNotCleanTaskBar>' 390 | Add-Content $unattendFile " <TimeZone>$TimeZoneName</TimeZone>" 391 | Add-Content $unattendFile ' </component>' 392 | Add-Content $unattendFile ' <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 393 | Add-Content $unattendFile ' <RunSynchronous>' 394 | Add-Content $unattendFile ' <RunSynchronousCommand wcm:action="add">' 395 | Add-Content $unattendFile ' <Description>EnableAdmin</Description>' 396 | Add-Content $unattendFile ' <Order>1</Order>' 397 | Add-Content $unattendFile ' <Path>cmd /c net user Administrator /active:yes</Path>' 398 | Add-Content $unattendFile ' </RunSynchronousCommand>' 399 | Add-Content $unattendFile ' <RunSynchronousCommand wcm:action="add">' 400 | Add-Content $unattendFile ' <Description>UnfilterAdministratorToken</Description>' 401 | Add-Content $unattendFile ' <Order>2</Order>' 402 | Add-Content $unattendFile ' <Path>cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v FilterAdministratorToken /t REG_DWORD /d 0 /f</Path>' 403 | Add-Content $unattendFile ' </RunSynchronousCommand>' 404 | Add-Content $unattendFile ' <RunSynchronousCommand wcm:action="add">' 405 | Add-Content $unattendFile ' <Description>disable user account page</Description>' 406 | Add-Content $unattendFile ' <Order>3</Order>' 407 | Add-Content $unattendFile ' <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v UnattendCreatedUser /t REG_DWORD /d 1 /f</Path>' 408 | Add-Content $unattendFile ' </RunSynchronousCommand>' 409 | Add-Content $unattendFile ' <RunSynchronousCommand wcm:action="add">' 410 | Add-Content $unattendFile ' <Description>disable async RunOnce</Description>' 411 | Add-Content $unattendFile ' <Order>4</Order>' 412 | Add-Content $unattendFile ' <Path>reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer /v AsyncRunOnce /t REG_DWORD /d 0 /f</Path>' 413 | Add-Content $unattendFile ' </RunSynchronousCommand>' 414 | Add-Content $unattendFile ' </RunSynchronous>' 415 | Add-Content $unattendFile ' </component>' 416 | Add-Content $unattendFile ' <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 417 | Add-Content $unattendFile " <InputLocale>$InputLocale</InputLocale>" 418 | Add-Content $unattendFile " <SystemLocale>$SystemLocale</SystemLocale>" 419 | Add-Content $unattendFile " <UILanguage>$UILanguage</UILanguage>" 420 | Add-Content $unattendFile " <UserLocale>$UserLocale</UserLocale>" 421 | Add-Content $unattendFile ' </component>' 422 | if ($OSDAdapter0IPAddressList -contains "DHCP") 423 | { 424 | Write-Verbose "IP is $OSDAdapter0IPAddressList so we prep for DHCP" 425 | } 426 | else 427 | { 428 | Write-Verbose "IP is $OSDAdapter0IPAddressList so we prep for Static IP" 429 | Add-Content $unattendFile ' <component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 430 | Add-Content $unattendFile ' <Interfaces>' 431 | Add-Content $unattendFile ' <Interface wcm:action="add">' 432 | Add-Content $unattendFile ' <DNSServerSearchOrder>' 433 | Add-Content $unattendFile " <IpAddress wcm:action=`"add`" wcm:keyValue=`"1`">$OSDAdapter0DNS1</IpAddress>" 434 | Add-Content $unattendFile " <IpAddress wcm:action=`"add`" wcm:keyValue=`"2`">$OSDAdapter0DNS2</IpAddress>" 435 | Add-Content $unattendFile ' </DNSServerSearchOrder>' 436 | Add-Content $unattendFile ' <Identifier>Ethernet</Identifier>' 437 | Add-Content $unattendFile ' </Interface>' 438 | Add-Content $unattendFile ' </Interfaces>' 439 | Add-Content $unattendFile ' </component>' 440 | Add-Content $unattendFile ' <component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 441 | Add-Content $unattendFile ' <Interfaces>' 442 | Add-Content $unattendFile ' <Interface wcm:action="add">' 443 | Add-Content $unattendFile ' <Ipv4Settings>' 444 | Add-Content $unattendFile ' <DhcpEnabled>false</DhcpEnabled>' 445 | Add-Content $unattendFile ' </Ipv4Settings>' 446 | Add-Content $unattendFile ' <Identifier>Ethernet</Identifier>' 447 | Add-Content $unattendFile ' <UnicastIpAddresses>' 448 | Add-Content $unattendFile " <IpAddress wcm:action=`"add`" wcm:keyValue=`"1`">$OSDAdapter0IPAddressList/$OSDAdapter0SubnetMaskPrefix</IpAddress>" 449 | Add-Content $unattendFile ' </UnicastIpAddresses>' 450 | Add-Content $unattendFile ' <Routes>' 451 | Add-Content $unattendFile ' <Route wcm:action="add">' 452 | Add-Content $unattendFile ' <Identifier>0</Identifier>' 453 | Add-Content $unattendFile " <NextHopAddress>$OSDAdapter0Gateways</NextHopAddress>" 454 | Add-Content $unattendFile " <Prefix>0.0.0.0/0</Prefix>" 455 | Add-Content $unattendFile ' </Route>' 456 | Add-Content $unattendFile ' </Routes>' 457 | Add-Content $unattendFile ' </Interface>' 458 | Add-Content $unattendFile ' </Interfaces>' 459 | Add-Content $unattendFile ' </component>' 460 | } 461 | Add-Content $unattendFile ' </settings>' 462 | Add-Content $unattendFile ' <settings pass="oobeSystem">' 463 | Add-Content $unattendFile ' <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">' 464 | Add-Content $unattendFile ' <UserAccounts>' 465 | Add-Content $unattendFile ' <AdministratorPassword>' 466 | Add-Content $unattendFile " <Value>$AdminPassword</Value>" 467 | Add-Content $unattendFile ' <PlainText>True</PlainText>' 468 | Add-Content $unattendFile ' </AdministratorPassword>' 469 | Add-Content $unattendFile ' </UserAccounts>' 470 | Add-Content $unattendFile ' <OOBE>' 471 | Add-Content $unattendFile ' <HideEULAPage>true</HideEULAPage>' 472 | Add-Content $unattendFile ' <HideLocalAccountScreen>true</HideLocalAccountScreen>' 473 | Add-Content $unattendFile ' <HideOnlineAccountScreens>true</HideOnlineAccountScreens>' 474 | Add-Content $unattendFile ' <NetworkLocation>Work</NetworkLocation>' 475 | Add-Content $unattendFile " <ProtectYourPC>$ProtectYourPC</ProtectYourPC>" 476 | Add-Content $unattendFile ' </OOBE>' 477 | Add-Content $unattendFile " <RegisteredOrganization>$Orgname</RegisteredOrganization>" 478 | Add-Content $unattendFile " <RegisteredOwner>$FullName</RegisteredOwner>" 479 | Add-Content $unattendFile " <TimeZone>$TimeZoneName</TimeZone>" 480 | Add-Content $unattendFile ' </component>' 481 | Add-Content $unattendFile ' <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 482 | Add-Content $unattendFile " <InputLocale>$InputLocale</InputLocale>" 483 | Add-Content $unattendFile " <SystemLocale>$SystemLocale</SystemLocale>" 484 | Add-Content $unattendFile " <UILanguage>$UILanguage</UILanguage>" 485 | Add-Content $unattendFile " <UserLocale>$UserLocale</UserLocale>" 486 | Add-Content $unattendFile ' </component>' 487 | Add-Content $unattendFile ' </settings>' 488 | Add-Content $unattendFile '</unattend>' 489 | Return $unattendFile 490 | } 491 | Function New-VIASetupCompletecmd 492 | { 493 | <# 494 | .Synopsis 495 | Short description 496 | .DESCRIPTION 497 | Long description 498 | .EXAMPLE 499 | Example of how to use this cmdlet 500 | .EXAMPLE 501 | Another example of how to use this cmdlet 502 | #> 503 | [cmdletbinding(SupportsShouldProcess=$True)] 504 | 505 | Param( 506 | $Command 507 | ) 508 | 509 | if((Test-Path -Path .\SetupComplete.cmd) -eq $true) 510 | { 511 | Remove-Item -Path .\SetupComplete.cmd 512 | } 513 | 514 | $unattendFile = New-Item -Path "SetupComplete.cmd" -type File 515 | Set-Content $unattendFile '@Echo off' 516 | Add-Content $unattendFile "$Command" 517 | Return $unattendFile 518 | } 519 | Function New-VIAISOImage 520 | { 521 | Param( 522 | $SourceFolder, 523 | $Destinationfile 524 | ) 525 | $Arguments = "-u2 ""$SourceFolder"" ""$Destinationfile""" 526 | Invoke-VIAExe -Executable 'C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe' -Arguments $Arguments 527 | } -------------------------------------------------------------------------------- /VIAHypervModule.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | VIAHypervModule 4 | .DESCRIPTION 5 | VIAHypervModule 6 | .EXAMPLE 7 | Import-Module C:\Setup\Functions\VIAHypervModule.psm1 8 | .NOTES 9 | http://www.deploymentbunny.com 10 | .COMPONENT 11 | HYDv10 12 | #> 13 | Function Get-VIAKVPData 14 | { 15 | <# 16 | .Synopsis 17 | Short description 18 | .DESCRIPTION 19 | Long description 20 | .EXAMPLE 21 | Example of how to use this cmdlet 22 | .EXAMPLE 23 | Another example of how to use this cmdlet 24 | #> 25 | [cmdletbinding(SupportsShouldProcess=$True)] 26 | 27 | Param( 28 | $VMName 29 | ) 30 | #Check if VM exists 31 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 32 | 33 | #Filter for parsing XML data 34 | filter Import-CimXml 35 | { 36 | $CimXml= [Xml]$_ 37 | $CimObj=New-Object -TypeName System.Object 38 | 39 | foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY")) 40 | { 41 | $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE 42 | } 43 | $CimObj 44 | } 45 | 46 | #Get the KVP data 47 | $Vm = Get-WmiObject -Namespace root\virtualization\v2 -Query "Select * From Msvm_ComputerSystem Where ElementName='$VMName'" -ErrorAction Stop 48 | $Kvp = Get-WmiObject -Namespace root\virtualization\v2 -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent" -ErrorAction Stop 49 | $Kvp.GuestExchangeItems | Import-CimXml 50 | } 51 | Function Test-VIAVMExists 52 | { 53 | <# 54 | .Synopsis 55 | Short description 56 | .DESCRIPTION 57 | Long description 58 | .EXAMPLE 59 | Example of how to use this cmdlet 60 | .EXAMPLE 61 | Another example of how to use this cmdlet 62 | #> 63 | [cmdletbinding(SupportsShouldProcess=$True)] 64 | 65 | Param( 66 | $VMname 67 | ) 68 | If ( ((Get-VM | Where-Object -Property Name -EQ -Value $VMname).Count) -eq "1"){ 69 | Return $true 70 | } 71 | else{ 72 | Return $False 73 | } 74 | } 75 | Function Test-VIAVMIsRunning 76 | { 77 | <# 78 | .Synopsis 79 | Short description 80 | .DESCRIPTION 81 | Long description 82 | .EXAMPLE 83 | Example of how to use this cmdlet 84 | .EXAMPLE 85 | Another example of how to use this cmdlet 86 | #> 87 | [cmdletbinding(SupportsShouldProcess=$True)] 88 | 89 | Param( 90 | $VMname 91 | ) 92 | #Check if VM exists 93 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 94 | 95 | if (((Get-VM -Name $VMname).State) -eq "Running"){ 96 | Return $true 97 | } 98 | else{ 99 | Return $False 100 | } 101 | } 102 | Function Test-VIAVMHaveICLoaded 103 | { 104 | <# 105 | .Synopsis 106 | Short description 107 | .DESCRIPTION 108 | Long description 109 | .EXAMPLE 110 | Example of how to use this cmdlet 111 | .EXAMPLE 112 | Another example of how to use this cmdlet 113 | #> 114 | [cmdletbinding(SupportsShouldProcess=$True)] 115 | 116 | Param( 117 | $VMname 118 | ) 119 | 120 | #Check if VM exists 121 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 122 | 123 | if (((Get-VM -Name $VMname).Heartbeat) -like "OK*"){ 124 | Return $true 125 | } 126 | else{ 127 | Return $False 128 | } 129 | } 130 | Function Test-VIAVMHaveIP 131 | { 132 | <# 133 | .Synopsis 134 | Short description 135 | .DESCRIPTION 136 | Long description 137 | .EXAMPLE 138 | Example of how to use this cmdlet 139 | .EXAMPLE 140 | Another example of how to use this cmdlet 141 | #> 142 | [cmdletbinding(SupportsShouldProcess=$True)] 143 | 144 | Param( 145 | $VMname 146 | ) 147 | #Check if VM exists 148 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 149 | 150 | if ((((Get-VMNetworkAdapter -VMName $VMname).IPAddresses[0]).count) -NE "0"){ 151 | Return $true 152 | } 153 | else{ 154 | Return $False 155 | } 156 | } 157 | Function Test-VIAVMHavePSDirect 158 | { 159 | <# 160 | .Synopsis 161 | Short description 162 | .DESCRIPTION 163 | Long description 164 | .EXAMPLE 165 | Example of how to use this cmdlet 166 | .EXAMPLE 167 | Another example of how to use this cmdlet 168 | #> 169 | [cmdletbinding(SupportsShouldProcess=$True)] 170 | 171 | Param( 172 | $VMname, 173 | $Credentials 174 | ) 175 | #Check if VM exists 176 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 177 | 178 | if((Invoke-Command -VMName $VMName -Credential $Credentials -ErrorAction SilentlyContinue {"Test"}) -ne "Test"){ 179 | Return $false 180 | } 181 | Else { 182 | Return $true 183 | } 184 | } 185 | Function Test-VIAVMDeployment 186 | { 187 | <# 188 | .Synopsis 189 | Short description 190 | .DESCRIPTION 191 | Long description 192 | .EXAMPLE 193 | Example of how to use this cmdlet 194 | .EXAMPLE 195 | Another example of how to use this cmdlet 196 | #> 197 | [cmdletbinding(SupportsShouldProcess=$True)] 198 | 199 | Param( 200 | $VMname 201 | ) 202 | #Check if VM exists 203 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 204 | 205 | If((Get-VIAKVPData -VMName $VMname | Where-Object -Property Name -EQ -Value OSDeployment).Data -eq "Done"){ 206 | Return $True 207 | } 208 | else 209 | { 210 | Return $False 211 | } 212 | } 213 | Function Test-VIAVMTaskSequenceDeployment 214 | { 215 | <# 216 | .Synopsis 217 | Short description 218 | .DESCRIPTION 219 | Long description 220 | .EXAMPLE 221 | Example of how to use this cmdlet 222 | .EXAMPLE 223 | Another example of how to use this cmdlet 224 | #> 225 | [cmdletbinding(SupportsShouldProcess=$True)] 226 | 227 | Param( 228 | $VMname 229 | ) 230 | #Check if VM exists 231 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 232 | 233 | If((Get-VIAKVPData -VMName $VMname | Where-Object -Property Name -EQ -Value TaskSequence).Data -eq "Done"){ 234 | Return $True 235 | } 236 | else 237 | { 238 | Return $False 239 | } 240 | } 241 | Function Wait-VIAVMExists 242 | { 243 | <# 244 | .Synopsis 245 | Short description 246 | .DESCRIPTION 247 | Long description 248 | .EXAMPLE 249 | Example of how to use this cmdlet 250 | .EXAMPLE 251 | Another example of how to use this cmdlet 252 | #> 253 | [cmdletbinding(SupportsShouldProcess=$True)] 254 | 255 | Param( 256 | $VMname 257 | ) 258 | #Check if VM exists 259 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 260 | 261 | do 262 | { 263 | Write-Verbose "Waiting for $VMname to exist" 264 | Start-Sleep -Seconds 2 265 | } 266 | until ((Test-VMExists -VMname $VMname) -eq $true) 267 | Write-Verbose "$VMname exists" 268 | } 269 | Function Wait-VIAVMIsRunning 270 | { 271 | <# 272 | .Synopsis 273 | Short description 274 | .DESCRIPTION 275 | Long description 276 | .EXAMPLE 277 | Example of how to use this cmdlet 278 | .EXAMPLE 279 | Another example of how to use this cmdlet 280 | #> 281 | [cmdletbinding(SupportsShouldProcess=$True)] 282 | 283 | Param( 284 | $VMname 285 | ) 286 | #Check if VM exists 287 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 288 | 289 | do 290 | { 291 | Write-Verbose "Waiting for $VMname is Running" 292 | Start-Sleep -Seconds 2 293 | } 294 | while ((Test-VIAVMIsRunning -VMname $VMname) -eq $false) 295 | Write-Verbose "$VMname is running" 296 | } 297 | Function Wait-VIAVMHaveICLoaded 298 | { 299 | <# 300 | .Synopsis 301 | Short description 302 | .DESCRIPTION 303 | Long description 304 | .EXAMPLE 305 | Example of how to use this cmdlet 306 | .EXAMPLE 307 | Another example of how to use this cmdlet 308 | #> 309 | [cmdletbinding(SupportsShouldProcess=$True)] 310 | 311 | Param( 312 | $VMname 313 | ) 314 | #Check if VM exists 315 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 316 | 317 | do 318 | { 319 | Write-Verbose "Waiting for $VMname to load IC's" 320 | Start-Sleep -Seconds 5 321 | } 322 | while ((Test-VIAVMHaveICLoaded -VMname $VMname) -eq $false) 323 | Write-Verbose "$VMname has IC's loaded" 324 | } 325 | Function Wait-VIAVMHaveIP 326 | { 327 | <# 328 | .Synopsis 329 | Short description 330 | .DESCRIPTION 331 | Long description 332 | .EXAMPLE 333 | Example of how to use this cmdlet 334 | .EXAMPLE 335 | Another example of how to use this cmdlet 336 | #> 337 | [cmdletbinding(SupportsShouldProcess=$True)] 338 | 339 | Param( 340 | $VMname 341 | ) 342 | #Check if VM exists 343 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 344 | 345 | do 346 | { 347 | Write-Verbose "Waiting for $VMname to get some kind of IP" 348 | Start-Sleep -Seconds 5 349 | } 350 | while ((Test-VIAVMIsRunning -VMname $VMname) -eq $false) 351 | Write-Verbose "$VMname has an IP" 352 | } 353 | Function Wait-VIAVMHavePSDirect 354 | { 355 | <# 356 | .Synopsis 357 | Short description 358 | .DESCRIPTION 359 | Long description 360 | .EXAMPLE 361 | Example of how to use this cmdlet 362 | .EXAMPLE 363 | Another example of how to use this cmdlet 364 | #> 365 | [cmdletbinding(SupportsShouldProcess=$True)] 366 | 367 | Param( 368 | $VMname, 369 | $Credentials 370 | ) 371 | #Check if VM exists 372 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 373 | 374 | do 375 | { 376 | Write-Verbose "Waiting for $VMname to give me PowerShell Direct access" 377 | Start-Sleep -Seconds 5 378 | } 379 | while ((Test-VIAVMHavePSDirect -VMname $VMname -Credentials $Credentials) -eq $false) 380 | Write-Verbose "$VMname has PowerShell Direct open" 381 | } 382 | Function Wait-VIAVMDeployment 383 | { 384 | <# 385 | .Synopsis 386 | Short description 387 | .DESCRIPTION 388 | Long description 389 | .EXAMPLE 390 | Example of how to use this cmdlet 391 | .EXAMPLE 392 | Another example of how to use this cmdlet 393 | #> 394 | [cmdletbinding(SupportsShouldProcess=$True)] 395 | 396 | Param( 397 | $VMname 398 | ) 399 | #Check if VM exists 400 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 401 | 402 | do 403 | { 404 | Write-Verbose "Waiting for $VMname to write ""Done"" in the KVP registry" 405 | Start-Sleep -Seconds 5 406 | } 407 | while ((Test-VIAVMDeployment -VMname $VMname) -eq $false) 408 | Write-Verbose "$VMname has written done in the KVP Registry" 409 | } 410 | Function Wait-VIAVMTaskSequenceDeployment 411 | { 412 | <# 413 | .Synopsis 414 | Short description 415 | .DESCRIPTION 416 | Long description 417 | .EXAMPLE 418 | Example of how to use this cmdlet 419 | .EXAMPLE 420 | Another example of how to use this cmdlet 421 | #> 422 | [cmdletbinding(SupportsShouldProcess=$True)] 423 | 424 | Param( 425 | $VMname 426 | ) 427 | #Check if VM exists 428 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 429 | 430 | do 431 | { 432 | Write-Verbose "Waiting for $VMname to finish TaskSequence in the KVP registry" 433 | Start-Sleep -Seconds 5 434 | } 435 | while ((Test-VIAVMTaskSequenceDeployment -VMname $VMname) -eq $false) 436 | Write-Verbose "$VMname has written done in the KVP Registry" 437 | } 438 | Function Mount-VIAVHDInFolder 439 | { 440 | <# 441 | .Synopsis 442 | Short description 443 | .DESCRIPTION 444 | Long description 445 | .EXAMPLE 446 | Example of how to use this cmdlet 447 | .EXAMPLE 448 | Another example of how to use this cmdlet 449 | #> 450 | [cmdletbinding(SupportsShouldProcess=$True)] 451 | 452 | Param( 453 | $VHDfile, 454 | $VHDClass, 455 | $MountFolder 456 | ) 457 | 458 | switch ($VHDClass) 459 | { 460 | UEFI {$PartitionNumber = 4} 461 | BIOS {$PartitionNumber = 2} 462 | DATA {$PartitionNumber = 1} 463 | Default {BREAK} 464 | } 465 | 466 | $VHD = Mount-VHD -Path $VHDfile -Passthru -NoDriveLetter 467 | $MountVHD = New-Item -Path $MountFolder -ItemType Directory -Force 468 | Add-PartitionAccessPath -DiskNumber $VHD.DiskNumber -PartitionNumber $PartitionNumber -AccessPath $($MountVHD.FullName) 469 | } 470 | Function Dismount-VIAVHDInFolder 471 | { 472 | <# 473 | .Synopsis 474 | Short description 475 | .DESCRIPTION 476 | Long description 477 | .EXAMPLE 478 | Example of how to use this cmdlet 479 | .EXAMPLE 480 | Another example of how to use this cmdlet 481 | #> 482 | [cmdletbinding(SupportsShouldProcess=$True)] 483 | 484 | Param( 485 | $VHDfile, 486 | $MountFolder 487 | ) 488 | Dismount-VHD -Path $VHDfile 489 | Remove-Item -Path $MountFolder -Force 490 | } 491 | Function Enable-VIANestedHyperV 492 | { 493 | <# 494 | .Synopsis 495 | Short description 496 | .DESCRIPTION 497 | Long description 498 | .EXAMPLE 499 | Example of how to use this cmdlet 500 | .EXAMPLE 501 | Another example of how to use this cmdlet 502 | #> 503 | [cmdletbinding(SupportsShouldProcess=$True)] 504 | 505 | Param( 506 | $VMname 507 | ) 508 | #Check if VM exists 509 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 510 | 511 | $VM = Get-VM -Name $VMname 512 | $VMNic = Get-VMNetworkAdapter -VM $VM 513 | $VMCPU = Get-VMProcessor -VM $VM 514 | 515 | #Check if VM is saved 516 | if($VM.State -eq 'Saved'){Write-Warning "$VMname is saved, needs to be off";BREAK} 517 | 518 | #Check if VM has Snapshots 519 | if($VM.ParentSnapshotName -ne $null){Write-Warning "$VMname has snapshots, remove them";BREAK} 520 | 521 | #Check if VM is off 522 | if($VM.State -ne 'Off'){Write-Warning "$VMname is is not turned off, needs to be off";BREAK} 523 | 524 | #Check VM Configuration Version 525 | if($VM.Version -lt 7.0){Write-Warning "$VMname is not upgraded, needs to run VM Configuration 7.0";BREAK} 526 | 527 | #Check if VM allows Snapshot 528 | if($VM.CheckpointType -ne 'Disabled'){Write-Warning "$VMname allow Snapshot, Modifying";Set-VM -VM $VM -CheckpointType Disabled} 529 | 530 | #Check if VM has Dynamic Memory Enabled 531 | if($VM.DynamicMemoryEnabled -eq $true){Write-Warning "$VMname is set for Dynamic Memory, Modifying";Set-VMMemory -VM $VM -DynamicMemoryEnabled $false} 532 | 533 | #Check if VM has more then 4GB of RAM 534 | if($VM.MemoryStartup -lt 4GB){Write-Warning "$VMname has less then 4 GB of ram assigned, Modifying";Set-VMMemory -VM $VM -StartupBytes 4GB} 535 | 536 | #Check if VM has Mac Spoofing Enabled 537 | if(($VMNic).MacAddressSpoofing -ne 'On'){Write-Warning "$VMname does not have Mac Address Spoofing enabled, Modifying";Set-VMNetworkAdapter -VM $VM -MacAddressSpoofing on} 538 | 539 | #Check if VM has Expose Virtualization Extensions Enabled 540 | if(($VMCPU).ExposeVirtualizationExtensions -ne $true){Write-Warning "$VMname is not set to Expose Virtualization Extensions, Modifying";Set-VMProcessor -VM $VM -ExposeVirtualizationExtensions $true} 541 | } 542 | Function Restart-VIAVM 543 | { 544 | param( 545 | $VMname 546 | ) 547 | 548 | Foreach($VM in $VMname){ 549 | #Check if VM exists 550 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 551 | 552 | Get-VM -VMName $VM | Stop-VM 553 | Get-VM -VMName $VM | Start-VM 554 | } 555 | } 556 | Function Start-VIAVM 557 | { 558 | param( 559 | $VMname, 560 | $domainCred 561 | ) 562 | 563 | Foreach($VM in $VMname){ 564 | #Check if VM exists 565 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 566 | 567 | Get-VM -VMName $VM | Start-VM 568 | Wait-VIAVMIsRunning -VMname $VMname 569 | Wait-VIAVMHaveICLoaded -VMname $VMname 570 | Wait-VIAVMHaveIP -VMname $VMname 571 | Wait-VIAVMHavePSDirect -VMname $VMname -Credentials $domainCred 572 | } 573 | } 574 | Function Copy-VIAVMFile 575 | { 576 | Param( 577 | $VMName, 578 | $SourceFolder 579 | ) 580 | Foreach($VM in $VMname){ 581 | #Check if VM exists 582 | if((Test-VIAVMExists -VMname $VMName) -eq $false){Write-Warning "Could find $VMName";break} 583 | IF((Test-VIAVMIsRunning -VMname $VMName) -eq $false){Write-Warning "$VMName is not running";break} 584 | $VMobj = Get-VM -VMName $VM 585 | 586 | #Copy scripts to VM 587 | $Contents = Get-ChildItem -Path $SourceFolder -Recurse -File *.* 588 | foreach($Item in $Contents){ 589 | foreach($server in $servers){ 590 | Copy-VMFile -VM $VMobj -SourcePath $Item.Fullname -DestinationPath $Item.Fullname -FileSource Host -CreateFullPath -Force 591 | } 592 | } 593 | } 594 | } 595 | Function New-VIAVM 596 | { 597 | <# 598 | .Synopsis 599 | Script for Deployment Fundamentals Vol 6 600 | .DESCRIPTION 601 | Script for Deployment Fundamentals Vol 6 602 | .EXAMPLE 603 | C:\Setup\Scripts\CreateNew-VM.ps1 -VMName DF6-DC01 -VMMem 1GB -VMvCPU 2 -VMLocation C:\VMs -DiskMode Empty -EmptyDiskSize 100GB -VMSwitchName Internal -ISO C:\Setup\ISO\HydrationDF6.iso -VMGeneration 2 604 | .NOTES 605 | Created: 2015-12-15 606 | Version: 1.0 607 | 608 | Author - Mikael Nystrom 609 | Twitter: @mikael_nystrom 610 | Blog : http://deploymentbunny.com 611 | 612 | Author - Johan Arwidmark 613 | Twitter: @jarwidmark 614 | Blog : http://deploymentresearch.com 615 | 616 | Disclaimer: 617 | This script is provided "AS IS" with no warranties, confers no rights and 618 | is not supported by the authors or Deployment Artist. 619 | .LINK 620 | http://www.deploymentfundamentals.com 621 | #> 622 | 623 | [cmdletbinding(SupportsShouldProcess=$True)] 624 | Param( 625 | [Parameter(mandatory=$True)] 626 | [ValidateNotNullOrEmpty()] 627 | [String] 628 | $VMName, 629 | 630 | [Parameter(mandatory=$false)] 631 | [ValidateNotNullOrEmpty()] 632 | #[Int] 633 | $VMMem = 1GB, 634 | 635 | [Parameter(mandatory=$false)] 636 | [ValidateNotNullOrEmpty()] 637 | [int] 638 | $VMvCPU = 1, 639 | 640 | [parameter(mandatory=$True)] 641 | [ValidateNotNullOrEmpty()] 642 | [String] 643 | $VMLocation = "C:\VMs", 644 | 645 | [parameter(mandatory=$false)] 646 | [ValidateNotNullOrEmpty()] 647 | [String] 648 | $VHDFile, 649 | 650 | [parameter(mandatory=$True)] 651 | [ValidateSet("Copy","Diff","Empty","Attached","None")] 652 | [String] 653 | $DiskMode = "Copy", 654 | 655 | [parameter(mandatory=$True)] 656 | [ValidateNotNullOrEmpty()] 657 | [String] 658 | $VMSwitchName, 659 | 660 | [parameter(mandatory=$False)] 661 | [ValidateNotNullOrEmpty()] 662 | [Int] 663 | $VlanID, 664 | 665 | [parameter(mandatory=$False)] 666 | [ValidateSet("1","2")] 667 | [Int] 668 | $VMGeneration, 669 | 670 | [parameter(mandatory=$false)] 671 | [ValidateNotNullOrEmpty()] 672 | [String] 673 | $ISO, 674 | 675 | [parameter(mandatory=$false)] 676 | [ValidateNotNullOrEmpty()] 677 | $EmptyDiskSize, 678 | 679 | [parameter(mandatory=$false)] 680 | [ValidateNotNullOrEmpty()] 681 | [switch] 682 | $DynaMem 683 | ) 684 | 685 | #Check if VM exists 686 | if((Test-VIAVMExists -VMname $VMName) -eq $true){Write-Warning "$VMName already exists";break} 687 | 688 | #Create VM 689 | $VM = New-VM -Name $VMName -MemoryStartupBytes $VMMem -Path $VMLocation -NoVHD -Generation $VMGeneration 690 | Remove-VMNetworkAdapter -VM $VM 691 | 692 | if($DynaMem -eq $True){ 693 | Write-Verbose "Configure dynamic memory" 694 | Set-VMMemory -VM $VM -DynamicMemoryEnabled $True -MaximumBytes $VMMem -MinimumBytes $VMMem -StartupBytes $VMMem 695 | }else{ 696 | Write-Verbose "Disable dynamic memory" 697 | Set-VMMemory -VM $VM -DynamicMemoryEnabled $false 698 | } 699 | 700 | 701 | 702 | 703 | #Add Networkadapter 704 | if($VMNetWorkType -eq "Legacy" -and $VMGeneration -eq "1") 705 | { 706 | Add-VMNetworkAdapter -VM $VM -SwitchName $VMSwitchName -IsLegacy $true 707 | } 708 | else 709 | { 710 | Add-VMNetworkAdapter -VM $VM -SwitchName $VMSwitchName 711 | } 712 | 713 | 714 | 715 | #Set vCPU 716 | if($VMvCPU -ne "1") 717 | { 718 | Set-VMProcessor -Count $VMvCPU -VM $VM 719 | } 720 | 721 | #Set VLAN 722 | If($VlanID -ne $NULL) 723 | { 724 | Set-VMNetworkAdapterVlan -VlanId $VlanID -Access -VM $VM 725 | } 726 | 727 | #Add Virtual Disk 728 | switch ($DiskMode) 729 | { 730 | Copy 731 | { 732 | $VHD = $VHDFile | Split-Path -Leaf 733 | Copy-Item $VHDFile -Destination "$VMLocation\$VMName\Virtual Hard Disks\" 734 | Add-VMHardDiskDrive -VM $VM -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHD" 735 | } 736 | Diff 737 | { 738 | $VHD = $VHDFile | Split-Path -Leaf 739 | New-VHD -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHD" -ParentPath $VHDFile -Differencing 740 | Add-VMHardDiskDrive -VMName $VMName -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHD" 741 | } 742 | Empty 743 | { 744 | $VHD = $VMName + ".vhdx" 745 | New-VHD -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHD" -SizeBytes $EmptyDiskSize -Dynamic 746 | Add-VMHardDiskDrive -VMName $VMName -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHD" 747 | } 748 | Attached 749 | { 750 | New-Item "$VMLocation\$VMName\Virtual Hard Disks" -ItemType directory -Force | Out-Null 751 | Add-VMHardDiskDrive -VM $VM -Path $VHDFile 752 | } 753 | None 754 | { 755 | } 756 | Default 757 | { 758 | Write-Error "Epic Failure" 759 | throw 760 | } 761 | } 762 | 763 | #Add DVD for Gen2 764 | if($VMGeneration -ne "1") 765 | { 766 | Add-VMDvdDrive -VMName $VMName 767 | } 768 | 769 | #Mount ISO 770 | if($ISO -ne '') 771 | { 772 | Set-VMDvdDrive -VMName $VMName -Path $ISO 773 | } 774 | 775 | #Set Correct Bootorder for Gen 2 776 | if($VMGeneration -ne "1") 777 | { 778 | $VMDvdDrive = Get-VMDvdDrive -VMName $VMName 779 | $VMHardDiskDrive = Get-VMHardDiskDrive -VM $VM 780 | $VMNetworkAdapter = Get-VMNetworkAdapter -VMName $VMName 781 | Set-VMFirmware -VM $VM -BootOrder $VMDvdDrive,$VMHardDiskDrive,$VMNetworkAdapter 782 | } 783 | Return (Get-VM -Id $vm.id) 784 | } 785 | Function Remove-VIAVM 786 | { 787 | <# 788 | .Synopsis 789 | Short description 790 | .DESCRIPTION 791 | Long description 792 | .EXAMPLE 793 | Example of how to use this cmdlet 794 | .EXAMPLE 795 | Another example of how to use this cmdlet 796 | #> 797 | [cmdletbinding(SupportsShouldProcess=$True)] 798 | 799 | Param 800 | ( 801 | [parameter(mandatory=$True,ValueFromPipelineByPropertyName=$true,Position=0)] 802 | [ValidateNotNullOrEmpty()] 803 | $VMName 804 | ) 805 | 806 | foreach($Item in $VMName){ 807 | $Items = Get-VM -Name $Item -ErrorAction SilentlyContinue 808 | If($Items.count -eq "0"){Break} 809 | foreach($Item in $Items){ 810 | Write-Verbose "Working on $Item" 811 | if($((Get-VM -Id $Item.Id).State) -eq "Running"){ 812 | Write-Verbose "Stopping $Item" 813 | Get-VM -Id $Item.Id | Stop-VM -Force -TurnOff 814 | } 815 | $Disks = Get-VMHardDiskDrive -VM $Item 816 | foreach ($Disk in $Disks){ 817 | Write-Verbose "Removing $($Disk.Path)" 818 | Remove-Item -Path $Disk.Path -Force -ErrorAction Continue 819 | } 820 | $ItemLoc = (Get-VM -Id $Item.id).ConfigurationLocation 821 | Write-Verbose "Removing $item" 822 | Get-VM -Id $item.Id | Remove-VM -Force 823 | Write-Verbose "Removing $ItemLoc" 824 | Remove-Item -Path $Itemloc -Recurse -Force 825 | } 826 | } 827 | } 828 | Function New-VIAVMHarddrive 829 | { 830 | [cmdletbinding(SupportsShouldProcess=$True)] 831 | 832 | Param 833 | ( 834 | [parameter(position=0,mandatory=$true)] 835 | [ValidateNotNullOrEmpty()] 836 | #[ValidateRange(20GB-500GB)] 837 | $VMname, 838 | 839 | [parameter(position=1,mandatory=$true)] 840 | [ValidateNotNullOrEmpty()] 841 | #[ValidateRange(1-10)] 842 | $NoOfDisks, 843 | 844 | [parameter(position=2,mandatory=$true)] 845 | [ValidateNotNullOrEmpty()] 846 | #[ValidateRange(20GB-500GB)] 847 | $DiskSize 848 | ) 849 | 850 | Foreach($DataDiskNo in (1..$NoOfDisks)){ 851 | $DataDiskPath = (Get-VM -Name $VMname).path + "\Virtual Hard Disks" 852 | $DataDiskName = "$VMname-DataDisk_$DataDiskNo" + ".vhdx" 853 | Write-Verbose "Add Datadisk if needed" 854 | Write-Verbose "Check if the darn disk already exist..." 855 | $DiskCheck =Test-Path ($DataDiskPath+"\"+$DataDiskName) 856 | if($DiskCheck -eq $false){ 857 | Write-Verbose ($DataDiskPath+"\"+$DataDiskName) 858 | $DataDiskToAdd = New-VHD -Path ($DataDiskPath+"\"+$DataDiskName) -Dynamic -SizeBytes $DiskSize -ErrorAction Stop 859 | Add-VMHardDiskDrive -Path $DataDiskToAdd.Path -VMName $VMname -ErrorAction Stop 860 | } 861 | else 862 | { 863 | Write-warning "Woops, disk is already created" 864 | } 865 | } 866 | } 867 | Function Test-VIAVMSwitchexistence 868 | { 869 | Param( 870 | [string]$VMSwitchname 871 | ) 872 | $Item = (Get-VMSwitch | Where-Object -Property Name -EQ -Value $VMSwitchname).count 873 | If($Item -eq '1'){Return $true}else{Return $false} 874 | } 875 | Function Compress-VIAVHD 876 | { 877 | Param( 878 | [string]$VHDFile 879 | ) 880 | Mount-VHD -Path $VHDFile -NoDriveLetter -ReadOnly 881 | Optimize-VHD -Path $VHDFile -Mode Full 882 | Dismount-VHD -Path $VHDFile 883 | } 884 | Function Get-VIAUnimportedvmcxFiles 885 | { 886 | <# 887 | .Synopsis 888 | Script used find not yet imported Hyper-V Configurations 889 | .DESCRIPTION 890 | Created: 2016-11-07 891 | Version: 1.0 892 | Author : Mikael Nystrom 893 | Twitter: @mikael_nystrom 894 | Blog : http://deploymentbunny.com 895 | Disclaimer: This script is provided "AS IS" with no warranties. 896 | .EXAMPLE 897 | Get-VIAUnimportedvmcxFiles 898 | #> 899 | [CmdletBinding(SupportsShouldProcess=$true)] 900 | 901 | Param( 902 | [string]$Folder 903 | ) 904 | 905 | $VMsIDs = (Get-VM).VMId 906 | $VMConfigs = (Get-ChildItem -Path $VMBaseFolder -Filter *.vmcx -Recurse).BaseName 907 | 908 | $obj = Compare-Object -ReferenceObject $VMsIDs -DifferenceObject $VMConfigs 909 | 910 | $Configs = foreach($Item in ($obj.InputObject)){ 911 | #$Item 912 | $Items = Get-ChildItem -Path $VMBaseFolder -Recurse -File -Filter *.vmcx | Where-Object -Property Basename -Like -Value "*$Item" 913 | $Items | Where-Object -Property FullName -NotLike -Value "*Snapshots*" 914 | } 915 | Return $Configs.FullName 916 | } 917 | Function Get-VIADisconnectedVHDs 918 | { 919 | <# 920 | .Synopsis 921 | Script used find .VHD files that are not connected to VM's 922 | .DESCRIPTION 923 | Created: 2016-11-07 924 | Version: 1.0 925 | Author : Mikael Nystrom 926 | Twitter: @mikael_nystrom 927 | Blog : http://deploymentbunny.com 928 | Disclaimer: This script is provided "AS IS" with no warranties. 929 | .EXAMPLE 930 | Get-Get-VIADisconnectedVHDs 931 | #> 932 | [CmdletBinding(SupportsShouldProcess=$true)] 933 | 934 | Param( 935 | [string]$Folder 936 | ) 937 | 938 | if((Test-Path -Path $Folder) -ne $true){ 939 | Write-Warning "I'm sorry, that folder does not exist" 940 | Break 941 | } 942 | 943 | #Get the disk used by a VM 944 | $VMs = (Get-VM | Where-Object -Property ParentSnapshotName -EQ -Value $null).VMId 945 | 946 | if(($VMs.count) -eq '0'){ 947 | Write-Information "Sorry, could not find any VM's" 948 | Break 949 | } 950 | $VHDsActive = foreach($VMsID in $VMs){ 951 | Get-VMHardDiskDrive -VM (Get-VM -Id $VMsID) 952 | } 953 | 954 | #Get the disk in the folder 955 | $VHDsAll = Get-ChildItem -Path $Folder -Filter *.vhd* -Recurse 956 | if(($VHDsAll.count) -eq '0'){ 957 | Write-Information "Sorry, could not find any VHD's in $folder" 958 | Break 959 | } 960 | 961 | $obj = Compare-Object -ReferenceObject $VHDsActive.Path -DifferenceObject $VHDsAll.FullName 962 | 963 | #Compare and give back the list of .vhd's that are not connected 964 | Return ($obj | Where-Object -Property SideIndicator -EQ -Value =>).InputObject 965 | } 966 | Function Get-VIAActiveDiffDisk 967 | { 968 | <# 969 | .Synopsis 970 | Script used to Deploy and Configure Fabric 971 | .DESCRIPTION 972 | Created: 2016-11-07 973 | Version: 1.0 974 | Author : Mikael Nystrom 975 | Twitter: @mikael_nystrom 976 | Blog : http://deploymentbunny.com 977 | Disclaimer: This script is provided "AS IS" with no warranties. 978 | .EXAMPLE 979 | Get-VIAActiveDiffDisk 980 | #> 981 | [CmdletBinding(SupportsShouldProcess=$true)] 982 | param( 983 | ) 984 | 985 | $VMHardDiskDrives = Get-VMHardDiskDrive -VM (Get-VM) 986 | $ActiveDisks = foreach($VMHardDiskDrive in $VMHardDiskDrives){ 987 | $Diffs = Get-VHD -Path $VMHardDiskDrive.Path | Where-Object -Property VhdType -EQ -Value Differencing 988 | $Diffs.ParentPath 989 | } 990 | $ActiveDisks | Sort-Object | Select-Object -Unique 991 | } 992 | Function Wait-VIAVMRestart 993 | { 994 | <# 995 | .Synopsis 996 | Script used to Deploy and Configure Fabric 997 | .DESCRIPTION 998 | Created: 2016-11-07 999 | Version: 1.0 1000 | Author : Mikael Nystrom 1001 | Twitter: @mikael_nystrom 1002 | Blog : http://deploymentbunny.com 1003 | Disclaimer: This script is provided "AS IS" with no warranties. 1004 | .EXAMPLE 1005 | Wait-VIAVMRestart -VMName FAADDS01 -Credentials $Credentials 1006 | #> 1007 | [CmdletBinding(SupportsShouldProcess=$true)] 1008 | Param( 1009 | $VMname, 1010 | $Credentials 1011 | ) 1012 | Restart-VIAVM -VMname $VMname 1013 | Wait-VIAVMIsRunning -VMname $VMname 1014 | Wait-VIAVMHaveICLoaded -VMname $VMname 1015 | Wait-VIAVMHaveIP -VMname $VMname 1016 | Wait-VIAVMHavePSDirect -VMname $VMname -Credentials $Credentials 1017 | } 1018 | Function Wait-VIAVMStart 1019 | { 1020 | <# 1021 | .Synopsis 1022 | Script used to Deploy and Configure Fabric 1023 | .DESCRIPTION 1024 | Created: 2016-11-07 1025 | Version: 1.0 1026 | Author : Mikael Nystrom 1027 | Twitter: @mikael_nystrom 1028 | Blog : http://deploymentbunny.com 1029 | Disclaimer: This script is provided "AS IS" with no warranties. 1030 | .EXAMPLE 1031 | Wait-VIAVMStart -VMName FAADDS01 -Credentials $Credentials 1032 | #> 1033 | [CmdletBinding(SupportsShouldProcess=$true)] 1034 | Param( 1035 | $VMname, 1036 | $Credentials 1037 | ) 1038 | Start-VM -VMname $VMname 1039 | Wait-VIAVMIsRunning -VMname $VMname 1040 | Wait-VIAVMHaveICLoaded -VMname $VMname 1041 | Wait-VIAVMHaveIP -VMname $VMname 1042 | Wait-VIAVMHavePSDirect -VMname $VMname -Credentials $Credentials 1043 | } 1044 | Function Wait-VIAVMADDSReady 1045 | { 1046 | <# 1047 | .Synopsis 1048 | Script used to Deploy and Configure Fabric 1049 | .DESCRIPTION 1050 | Created: 2016-12-14 1051 | Version: 1.0 1052 | Author : Mikael Nystrom 1053 | Twitter: @mikael_nystrom 1054 | Blog : http://deploymentbunny.com 1055 | Disclaimer: This script is provided "AS IS" with no warranties. 1056 | .EXAMPLE 1057 | Wait-VIAVMADDSReady -VMName FAADDS01 -Credentials $Credentials 1058 | #> 1059 | 1060 | [CmdletBinding(SupportsShouldProcess=$true)] 1061 | Param( 1062 | $VMname, 1063 | $Credentials 1064 | ) 1065 | 1066 | #Check that ADDS is up and running 1067 | do{ 1068 | $result = Invoke-Command -VMName $VMname -ScriptBlock { 1069 | Test-Path -Path \\$env:computername\NETLOGON 1070 | } -Credential $Credentials 1071 | Write-Verbose "Waiting for Domain Controller to be operational..." 1072 | Start-Sleep -Seconds 30 1073 | }until($result -eq $true) 1074 | Write-Verbose "Waiting for Domain Controller is now operational..." 1075 | } 1076 | Function Enable-VIAVMDeviceNaming 1077 | { 1078 | <# 1079 | .Synopsis 1080 | Script used to Deploy and Configure Fabric 1081 | .DESCRIPTION 1082 | Created: 2016-12-14 1083 | Version: 1.0 1084 | Author : Mikael Nystrom 1085 | Twitter: @mikael_nystrom 1086 | Blog : http://deploymentbunny.com 1087 | Disclaimer: This script is provided "AS IS" with no warranties. 1088 | .EXAMPLE 1089 | Wait-VIAVMADDSReady -VMName FAADDS01 -Credentials $Credentials 1090 | #> 1091 | 1092 | [CmdletBinding(SupportsShouldProcess=$true)] 1093 | Param( 1094 | $VMName 1095 | ) 1096 | 1097 | Get-VMNetworkAdapter -VMName $VMName | Set-VMNetworkAdapter -DeviceNaming On 1098 | } 1099 | -------------------------------------------------------------------------------- /VIANicModule.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | FANicUtility.psm1 4 | .DESCRIPTION 5 | FANicUtility.psm1 6 | .EXAMPLE 7 | Example of how to use this cmdlet 8 | #> 9 | 10 | function Rename-VIANetAdapter 11 | { 12 | <# 13 | .Synopsis 14 | Rename-FANetAdapter 15 | .DESCRIPTION 16 | Rename-FANetAdapter is a part of HYDV6 17 | .EXAMPLE 18 | Example of how to use this cmdlet 19 | #> 20 | Param( 21 | [Parameter(Mandatory=$true, 22 | ValueFromPipelineByPropertyName=$true, 23 | Position=0)] 24 | $NetAdapterMacAddress, 25 | 26 | [Parameter(Mandatory=$true, 27 | ValueFromPipelineByPropertyName=$true, 28 | Position=1)] 29 | $NetAdapterNewName 30 | ) 31 | Foreach($Item in $NetAdapterMacAddress){ 32 | Write-Verbose "Looking for $Item" 33 | $NIC = Get-NetAdapter -Physical | Where-Object -Property MacAddress -EQ -Value $($Item.Replace(":","-")) 34 | Rename-NetAdapter -InputObject $NIC -NewName $NetAdapterNewName 35 | } 36 | } 37 | function Disable-VIADisconnectedNetAdapter 38 | { 39 | <# 40 | .Synopsis 41 | Disable-VIADisconnectedNetAdapter 42 | .DESCRIPTION 43 | Disable-VIADisconnectedNetAdapter is a part of HYDV6 44 | .EXAMPLE 45 | Disable-VIADisconnectedNetAdapter 46 | #> 47 | $Nics = Get-NetAdapter -Physical | Where-Object -Property Status -EQ -Value Disconnected 48 | Foreach($Item in $Nics){ 49 | Write-Verbose "Looking for $Item" 50 | Disable-NetAdapter -InputObject $Item -Confirm:$false 51 | } 52 | } 53 | Function Convert-VIASubnet 54 | { 55 | <# 56 | .SYNOPSIS 57 | Converts between PrefixLength and subnet mask. 58 | 59 | 60 | .DESCRIPTION 61 | This script converts between PrefixLength and subnet mask parameters, these parameters define the size of a subnet for IPv4 addresses. 62 | This script assumes valid subnet mask input and does not support scenarios such as non-contiguous subnet masks. 63 | 64 | 65 | .INPUTS 66 | None 67 | 68 | .OUTPUTS 69 | The script outputs a PrefixLength if SubnetMask was entered, or a SubnetMask if a PrefixLength was entered. 70 | 71 | .NOTES 72 | Requires Windows 8 or later. 73 | 74 | #> 75 | 76 | 77 | param( 78 | 79 | [Parameter(ParameterSetName="SubnetMask",Mandatory=$True)][string]$SubnetMask, 80 | [Parameter(ParameterSetName="PrefixLength",Mandatory=$True)][int]$PrefixLength) 81 | 82 | 83 | #################################### 84 | #User provided a prefix 85 | if ($PrefixLength) 86 | { 87 | $PrefixLengthReturn = $PrefixLength 88 | if ($PrefixLength -gt 32) 89 | { 90 | write-host "Invalid input, prefix length must be less than 32" 91 | exit(1) 92 | } 93 | 94 | $bitArray="" 95 | for($bitCount = 0; $PrefixLength -ne "0"; $bitCount++) 96 | { 97 | $bitArray += '1' 98 | $PrefixLength = $PrefixLength - 1; 99 | } 100 | 101 | #################################### 102 | #Fill in the rest with zeroes 103 | While ($bitCount -ne 32) 104 | { 105 | $bitArray += '0' 106 | $bitCount++ 107 | } 108 | #################################### 109 | #Convert the bit array into subnet mask 110 | $ClassAAddress = $bitArray.SubString(0,8) 111 | $ClassAAddress = [Convert]::ToUInt32($ClassAAddress, 2) 112 | $ClassBAddress = $bitArray.SubString(8,8) 113 | $ClassBAddress = [Convert]::ToUInt32($ClassBAddress, 2) 114 | $ClassCAddress = $bitArray.SubString(16,8) 115 | $ClassCAddress = [Convert]::ToUInt32($ClassCAddress, 2) 116 | $ClassDAddress = $bitArray.SubString(24,8) 117 | $ClassDAddress = [Convert]::ToUInt32($ClassDAddress, 2) 118 | 119 | $SubnetMaskReturn = "$ClassAAddress.$ClassBAddress.$ClassCAddress.$ClassDAddress" 120 | } 121 | 122 | #################################### 123 | ##User provided a subnet mask 124 | if ($SubnetMask) 125 | { 126 | #################################### 127 | #Ensure valid IP address input. Note this does not check for non-contiguous subnet masks! 128 | $Address=[System.Net.IPaddress]"0.0.0.0" 129 | Try 130 | { 131 | $IsValidInput=[System.Net.IPaddress]::TryParse($SubnetMask, [ref]$Address) 132 | } 133 | Catch 134 | { 135 | 136 | } 137 | Finally 138 | { 139 | 140 | } 141 | 142 | if ($IsValidInput -eq $False) 143 | { 144 | Write-Host "Invalid Input. Please enter a properly formatted subnet mask." 145 | Exit(1) 146 | } 147 | 148 | #################################### 149 | #Convert subnet mask to prefix length 150 | If($IsValidInput) 151 | { 152 | $PrefixArray=@() 153 | $PrefixLength = 0 154 | $ByteArray = $SubnetMask.Split(".") 155 | 156 | #################################### 157 | #This loop converts the bytes to bits, add zeroes when necessary 158 | for($byteCount = 0; $byteCount-lt 4; $byteCount++) 159 | { 160 | $bitVariable = $ByteArray[$byteCount] 161 | $bitVariable = [Convert]::ToString($bitVariable, 2) 162 | 163 | if($bitVariable.Length -lt 8) 164 | { 165 | $NumOnes=$bitVariable.Length 166 | $NumZeroes=8-$bitVariable.Length 167 | 168 | for($bitCount=0; $bitCount -lt $NumZeroes; $bitCount++) 169 | { 170 | $Temp=$Temp+"0" 171 | } 172 | 173 | $bitVariable=$Temp+$bitVariable 174 | } 175 | 176 | #################################### 177 | #This loop counts the bits in the prefix 178 | for($bitCount=0; $bitCount -lt 8; $bitCount++) 179 | { 180 | if ($bitVariable[$bitCount] -eq "1") 181 | { 182 | $PrefixLength++ 183 | } 184 | 185 | $PrefixArray=$PrefixArray + ($bitVariable[$bitCount]) 186 | 187 | } 188 | } 189 | 190 | #################################### 191 | #Check if the subnet mask was contiguous, fail if it wasn't. 192 | $Mark=$False 193 | 194 | foreach ($bit in $PrefixArray) 195 | { 196 | if($bit -eq "0") 197 | { 198 | if($Mark -eq $False) 199 | { 200 | $Mark=$True 201 | } 202 | } 203 | if($bit -eq "1") 204 | { 205 | if($Mark -eq $True) 206 | { 207 | Write-Host "Invalid Input. Please enter a properly formatted subnet mask." 208 | Exit(1) 209 | } 210 | } 211 | 212 | } 213 | 214 | $SubnetMaskReturn = $SubnetMask 215 | $PrefixLengthReturn = $PrefixLength 216 | } 217 | } 218 | ##Create the object to be returned to the console 219 | $Return = new-object Object 220 | Add-Member -InputObject $Return -Name PrefixLength -Value $PrefixLengthReturn -Type NoteProperty 221 | Add-Member -InputObject $Return -Name SubnetMask -Value $SubnetMaskReturn -Type NoteProperty 222 | $Return 223 | } 224 | function Rename-VIANetAdapterUsingDeviceNaming 225 | { 226 | [cmdletbinding(SupportsShouldProcess=$True)] 227 | Param( 228 | $VMDeviceName 229 | ) 230 | Get-NetAdapter | Disable-NetAdapter -Confirm:$false 231 | Get-NetAdapter | Enable-NetAdapter -Confirm:$false 232 | $NIC = (Get-NetAdapterAdvancedProperty -Name * | Where-Object -FilterScript {$_.DisplayValue -eq $VMDeviceName}).Name 233 | Rename-NetAdapter -Name $NIC -NewName $VMDeviceName 234 | } 235 | 236 | 237 | -------------------------------------------------------------------------------- /VIARacAdm.psm1: -------------------------------------------------------------------------------- 1 | Function Add-VIARacAdmUser { 2 | Param ( 3 | $RACRootUser, 4 | $RACRootUserPass, 5 | $IPAddress, 6 | $Index = "3", 7 | $UserToAdd, 8 | $PasswordToAdd 9 | ) 10 | 11 | $RACADMExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe" 12 | $PrivilegeToAdd ="0x000001ff" 13 | 14 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -o cfgUserAdminUserName -i $Index $UserToAdd 15 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -o cfgUserAdminPassword -i $Index $PasswordToAdd 16 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -i $Index -o cfgUserAdminPrivilege $PrivilegeToAdd 17 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -i $Index -o cfgUserAdminEnable 1 18 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -i $Index -o cfgUserAdminIpmiLanPrivilege 4 19 | } 20 | Function Remove-VIARacAdmUser { 21 | Param ( 22 | $RACRootUser, 23 | $RACRootUserPass, 24 | $IPAddress, 25 | $Index = "3" 26 | ) 27 | 28 | $RACADMExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe" 29 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgUserAdmin -o cfgUserAdminUserName -i $Index `"`" 2>&1 30 | } 31 | Function Enable-VIARacAdmIPMI { 32 | Param ( 33 | $IPAddress, 34 | $RACRootUser, 35 | $RACRootUserPass 36 | ) 37 | $RACADMExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe" 38 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgIpmiLan -o cfgIpmiLanEnable 1 39 | } 40 | Function Set-VIARacAdmPower { 41 | Param ( 42 | $IPAddress, 43 | $RACRootUser, 44 | $RACRootUserPass, 45 | $Mode 46 | ) 47 | $RACADMExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe" 48 | switch ($Mode) 49 | { 50 | 'Off' { 51 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass serveraction powerdown 52 | } 53 | 'On' { 54 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass serveraction powerup 55 | } 56 | Default {} 57 | } 58 | } 59 | Function Set-VIARacAdmNextBoot { 60 | Param ( 61 | $IPAddress, 62 | $RACRootUser, 63 | $RACRootUserPass, 64 | $Mode 65 | ) 66 | $RACADMExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe" 67 | switch ($Mode) 68 | { 69 | 'PXE' { 70 | & $RACADMExe -r $IPAddress -u $RACRootUser -p $RACRootUserPass config -g cfgServerInfo -o cfgServerFirstBootDevice PXE 71 | } 72 | Default {} 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /VIASCVMMModule.psm1: -------------------------------------------------------------------------------- 1 | #Import Drivers in SCVMM Lib 2 | Function Import-VIASCVMDriver 3 | { 4 | param( 5 | $SCVMMLibPath, 6 | $LocalDriversPath 7 | ) 8 | Copy-item -Path "$LocalDriversPath" -Destination "$SCVMMLibPath" -Recurse 9 | Get-SCLibraryShare | Read-SCLibraryShare 10 | } 11 | Function Set-VIASCVMDriverTag 12 | { 13 | Param( 14 | $TagName, 15 | $SourceFolder 16 | ) 17 | $Inffiles = Get-ChildItem -Path $SourceFolder -filter *.inf -Recurse 18 | foreach ($Inffile in $Inffiles) 19 | { 20 | $DriverFile = $Inffile.FullName 21 | $DriverPackage = Get-SCDriverPackage | Where-Object {$_.SharePath -eq $DriverFile} 22 | $DriverPackage.SharePath 23 | Set-SCDriverPackage -DriverPackage $DriverPackage -Tag $TagName -RunAsynchronously 24 | } 25 | } 26 | Function Install-VIAHPSUM($HostName) 27 | { 28 | $VMHost = Get-SCVMHost -ComputerName $HostName 29 | $scriptSetting = New-SCScriptCommandSetting 30 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $True 31 | $CommandParams = "/c PowerShell.exe -ExecutionPolicy Bypass -File \\fadepl01\ApplicationRoot\install-HPSUM\Install-HPSUM.ps1" 32 | $Command = "CMD.exe" 33 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 1800 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 34 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 35 | do {} 36 | While($scriptjob.status -eq 'Running') 37 | } 38 | Function Start-VIAMaintMode($HostName) 39 | { 40 | #Set in MainMode 41 | $VMHost = Get-SCVMHost -ComputerName $HostName 42 | Disable-SCVMHost -VMHost $VMHost -Verbose 43 | Start-Sleep 2 44 | } 45 | Function Stop-VIAMaintMode($HostName) 46 | { 47 | #Set in MainMode 48 | $VMHost = Get-SCVMHost -ComputerName $HostName 49 | Enable-SCVMHost -VMHost $VMHost -Verbose 50 | Start-Sleep 2 51 | } 52 | Function Set-VIADisconnectedNicsDisable($HostName) 53 | { 54 | $VMHost = Get-SCVMHost -ComputerName $HostName 55 | $scriptSetting = New-SCScriptCommandSetting 56 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 57 | $CommandParams = "/c PowerShell.exe -ExecutionPolicy Bypass -File \\fadepl01\ApplicationRoot\Maint\SetFADisconnectedNicsDisable.ps1" 58 | $Command = "CMD.exe" 59 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 60 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 60 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 61 | do {} 62 | While($scriptjob.status -eq 'Running') 63 | } 64 | function Get-VIASCVMHostRefresh($HostName) 65 | { 66 | $VMHost = Get-SCVMHost -ComputerName $HostName 67 | Read-SCVMHost -VMHost $VMHost 68 | Read-SCVirtualMachine -VMHost $VMHost 69 | } 70 | function Add-VIAAdmintools($HostName) 71 | { 72 | $VMHost = Get-SCVMHost -ComputerName $HostName 73 | $scriptSetting = New-SCScriptCommandSetting 74 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 75 | $CommandParams = "/c powershell.exe -Command Add-WindowsFeature -Name RSAT-Hyper-V-Tools" 76 | $Command = "CMD.exe" 77 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 120 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 78 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 79 | do {} 80 | While($scriptjob.status -eq 'Running') 81 | } 82 | Function Install-VIAProWin64($HostName) 83 | { 84 | $VMHost = Get-SCVMHost -ComputerName $HostName 85 | $scriptSetting = New-SCScriptCommandSetting 86 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 87 | $CommandParams = "/c \\fadepl01\ApplicationRoot\Install-ProWin64\Source\APPS\PROSETDX\Winx64\DxSetup.exe /qn " 88 | $Command = "CMD.exe" 89 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 90 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 91 | do {} 92 | While($scriptjob.status -eq 'Running') 93 | } 94 | Function Set-VIAIntelNicForHyperVOnly($HostName) 95 | { 96 | $VMHost = Get-SCVMHost -ComputerName $HostName 97 | $scriptSetting = New-SCScriptCommandSetting 98 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 99 | $CommandParams = "/c PowerShell.exe -ExecutionPolicy Bypass -File \\fadepl01\ApplicationRoot\Maint\SetFAIntelNicForHyperVOnly.ps1" 100 | $Command = "CMD.exe" 101 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 240 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 102 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 103 | do {} 104 | While($scriptjob.status -eq 'Running') 105 | } 106 | Function Install-VIADellOMSU($HostName) 107 | { 108 | $VMHost = Get-SCVMHost -ComputerName $HostName 109 | $scriptSetting = New-SCScriptCommandSetting 110 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 111 | $CommandParams = "/c msiexec.exe /i \\fadepl01\ApplicationRoot\Install-HardwareApps\Source\Dell\OMSU\OpenManage\windows\SystemsManagementx64\SysMgmtx64.msi /qb" 112 | $Command = "CMD.exe" 113 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 114 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 115 | do {} 116 | While($scriptjob.status -eq 'Running') 117 | } 118 | Function Install-VIADellDriverPackForR730($HostName) 119 | { 120 | $VMHost = Get-SCVMHost -ComputerName $HostName 121 | $scriptSetting = New-SCScriptCommandSetting 122 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 123 | $CommandParams = "/c \\fadepl01\ApplicationRoot\Install-Drivers\Source\Dell\Drivers-for-OS-Deployment_Application_TPJWF_WN64_15.04.07_A00.EXE /s" 124 | $Command = "CMD.exe" 125 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 126 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 127 | do {} 128 | While($scriptjob.status -eq 'Running') 129 | } 130 | Function Install-VIADellChipSetDriverForR730($HostName) 131 | { 132 | $VMHost = Get-SCVMHost -ComputerName $HostName 133 | $scriptSetting = New-SCScriptCommandSetting 134 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 135 | $CommandParams = "/c \\fadepl01\ApplicationRoot\Install-Drivers\Source\Dell\Chipset_Driver_1MM6C_WN_9.4.2.1019_A02\Setup.exe /s /v/qn" 136 | $Command = "CMD.exe" 137 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 138 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 139 | do {} 140 | While($scriptjob.status -eq 'Running') 141 | } 142 | Function Install-VIADellPERC($HostName) 143 | { 144 | $VMHost = Get-SCVMHost -ComputerName $HostName 145 | $scriptSetting = New-SCScriptCommandSetting 146 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $true 147 | $CommandParams = "/c \\fadepl01\ApplicationRoot\Install-PERC\Source\SAS-RAID_Driver_2D7H2_WN64_6.602.07.00_A00.EXE /s" 148 | $Command = "CMD.exe" 149 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 150 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 151 | do {} 152 | While($scriptjob.status -eq 'Running') 153 | } 154 | Function Set-VIALiveMig($HostName,$LiveMigrationSubnets) 155 | { 156 | $VMHost = Get-SCVMHost -ComputerName $HostName 157 | Set-SCVMHost -VMHost $vmHost -LiveStorageMigrationMaximum "4" -EnableLiveMigration $true -LiveMigrationMaximum "4" -MigrationPerformanceOption "UseCompression" -MigrationAuthProtocol "CredSSP" -UseAnyMigrationSubnet $false -MigrationSubnet $LiveMigrationSubnets 158 | } 159 | Function Enable-VIARDPAccess 160 | { 161 | Param( 162 | $SCVMMHostName 163 | ) 164 | $VMHost = Get-SCVMHost -ComputerName $HostName 165 | $scriptSetting = New-SCScriptCommandSetting 166 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 167 | $CommandParams = "/c cscript.exe C:\windows\system32\SCregEdit.wsf /AR 0" 168 | $Command = "CMD.exe" 169 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 170 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 171 | do {} 172 | While($scriptjob.status -eq 'Running') 173 | } 174 | Function Disable-VIARDPSecurity 175 | { 176 | Param( 177 | $SCVMMHostName 178 | ) 179 | $VMHost = Get-SCVMHost -ComputerName $HostName 180 | $scriptSetting = New-SCScriptCommandSetting 181 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 182 | $CommandParams = "/c cscript.exe C:\windows\system32\SCregEdit.wsf /CS 0" 183 | $Command = "CMD.exe" 184 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 185 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 186 | do {} 187 | While($scriptjob.status -eq 'Running') 188 | } 189 | Function Enable-VIARDPFirewallRules 190 | { 191 | Param( 192 | $SCVMMHostName 193 | ) 194 | 195 | $VMHost = Get-SCVMHost -ComputerName $HostName 196 | $scriptSetting = New-SCScriptCommandSetting 197 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $false 198 | $CommandParams = '/c PowerShell.exe -Command "Get-NetFirewallRule | Where-Object -Property DisplayName -like -Value "*Remote*" | Enable-NetFirewallRule"' 199 | $Command = "CMD.exe" 200 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $CommandParams -VMHost $VMHost -ScriptCommandSetting $scriptSetting 201 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 202 | do {} 203 | While($scriptjob.status -eq 'Running') 204 | } 205 | Function Install-VIASCVMMHostApplication 206 | { 207 | Param( 208 | $SCVMMHostName, 209 | $Command, 210 | $Arguments, 211 | $Reboot 212 | ) 213 | 214 | $VMHost = Get-SCVMHost -ComputerName $SCVMMHostName 215 | $ScriptSetting = New-SCScriptCommandSetting 216 | Set-SCScriptCommandSetting -ScriptCommandSetting $scriptSetting -WorkingDirectory "" -PersistStandardOutputPath "" -PersistStandardErrorPath "" -MatchStandardOutput "" -MatchStandardError "" -MatchExitCode "" -WarnAndContinueOnMatch -RestartOnRetry $false -MatchRebootExitCode "{1}|{3010}|{3011}" -RestartScriptOnExitCodeReboot $false -AlwaysReboot $true 217 | $Arguments = "/c \\fadepl01\ApplicationRoot\Install-PERC\Source\SAS-RAID_Firmware_WN0HC_WN64_25.3.0.0016_A04.EXE /s" 218 | 219 | Invoke-SCScriptCommand -Executable $Command -TimeoutSeconds 900 -CommandParameters $Arguments -VMHost $VMHost -ScriptCommandSetting $scriptSetting 220 | $ScriptJob = Get-SCJob -newest 3 | where { $_.Status -eq "Running" -and $_.Name -Like "Invoke script command ($Command $CommandParams)" } 221 | do {} 222 | While($scriptjob.status -eq 'Running') 223 | } 224 | Function Remove-VIASCVMMHost { 225 | Param( 226 | $VMHostName, 227 | $SCVMMAdminAccountName, 228 | $DNSServerName, 229 | $DNSZoneName 230 | ) 231 | 232 | Import-Module -Name virtualmachinemanager -ErrorAction Stop 233 | Import-Module -Name virtualmachinemanagercore -ErrorAction Stop 234 | Import-Module -Name ActiveDirectory -ErrorAction Stop 235 | Import-Module -Name DNSserver -ErrorAction Stop 236 | 237 | $SCRunAsAccount = Get-SCRunAsAccount -VMMServer FASCVM01 -Name $SCVMMAdminAccountName 238 | Get-SCVMHost | where ComputerName -EQ $VMHostName | Remove-SCVMHost -Credential $SCRunAsAccount -ErrorAction Continue 239 | Remove-ADobject (Get-ADComputer $VMHostName).distinguishedname -Recursive -Confirm:$false -ErrorAction Continue 240 | Get-DnsServerResourceRecord -Name $VMHostName -ComputerName $DNSServerName -ZoneName $DNSZoneName | Remove-DnsServerResourceRecord -ZoneName $DNSZoneName -ComputerName $DNSServerName -Confirm:$false -Force -ErrorAction Continue 241 | } 242 | -------------------------------------------------------------------------------- /VIAStorageModule.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | VIAUtility.psm1 4 | .DESCRIPTION 5 | VIAUtility.psm1 6 | .EXAMPLE 7 | Example of how to use this cmdlet 8 | #> 9 | <# 10 | #> 11 | Function Initialize-VIADataDisk 12 | { 13 | Param( 14 | [parameter(position=0,mandatory=$true)] 15 | [ValidateNotNullOrEmpty()] 16 | [ValidateSet('NTFS','ReFS','NA')] 17 | $FileSystem = 'NTFS', 18 | $DiskNumber = '1', 19 | $PartitionType = 'GPT', 20 | $FileSystemLabel = 'Datadisk01' 21 | ) 22 | Write-Verbose "Working on disk: $DiskNumber" 23 | if($FileSystem -eq 'NA'){}else{ 24 | Initialize-Disk -Number $DiskNumber –PartitionStyle $PartitionType 25 | $Drive = New-Partition -DiskNumber $DiskNumber -GptType '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}' -UseMaximumSize 26 | $Drive | Format-Volume -FileSystem $FileSystem -NewFileSystemLabel $FileSystemLabel 27 | Add-PartitionAccessPath -DiskNumber $DiskNumber -PartitionNumber $Drive.PartitionNumber -AssignDriveLetter 28 | $Drive = Get-Partition -DiskNumber $DiskNumber -PartitionNumber $Drive.PartitionNumber 29 | } 30 | } 31 | Function New-VIAVHD 32 | { 33 | [CmdletBinding(SupportsShouldProcess=$true)] 34 | 35 | Param( 36 | [Parameter(Position=0)] 37 | [ValidateNotNullOrEmpty()] 38 | [string] 39 | $VHDFile, 40 | 41 | [Parameter(Position=1)] 42 | [ValidateNotNullOrEmpty()] 43 | [string] 44 | $VHDSizeinMB, 45 | 46 | [Parameter(Position=2)] 47 | [ValidateNotNullOrEmpty()] 48 | [ValidateSet('EXPANDABLE','FIXED')] 49 | [string] 50 | $VHDType 51 | ) 52 | 53 | if(!(Test-Path -Path ($VHDFile | Split-Path -Parent))){ 54 | throw "Folder does not exists..."} 55 | 56 | #Check if file exists 57 | if(Test-Path -Path $VHDFile){ 58 | throw "File exists..."} 59 | 60 | $diskpartcmd = New-Item -Path $env:TEMP\diskpartcmd.txt -ItemType File -Force 61 | Set-Content -Path $diskpartcmd -Value "CREATE VDISK FILE=""$VHDFile"" MAXIMUM=$VHDSizeinMB TYPE=$VHDType" 62 | $Exe = "DiskPart.exe" 63 | $Args = "-s $($diskpartcmd.FullName)" 64 | Invoke-VIAExe -Executable $Exe -Arguments $Args -SuccessfulReturnCode 0 65 | Remove-Item $diskpartcmd -Force -ErrorAction SilentlyContinue 66 | } 67 | -------------------------------------------------------------------------------- /VIAUtilityModule.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | VIAUtility.psm1 4 | .DESCRIPTION 5 | VIAUtility.psm1 6 | .EXAMPLE 7 | Example of how to use this cmdlet 8 | #> 9 | Function Invoke-VIAExe 10 | { 11 | [CmdletBinding(SupportsShouldProcess=$true)] 12 | 13 | param( 14 | [parameter(mandatory=$true,position=0)] 15 | [ValidateNotNullOrEmpty()] 16 | [string] 17 | $Executable, 18 | 19 | [parameter(mandatory=$true,position=1)] 20 | [ValidateNotNullOrEmpty()] 21 | [string] 22 | $Arguments, 23 | 24 | [parameter(mandatory=$false,position=2)] 25 | [ValidateNotNullOrEmpty()] 26 | [int] 27 | $SuccessfulReturnCode = 0 28 | ) 29 | 30 | Write-Verbose "Running $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru" 31 | $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru 32 | 33 | Write-Verbose "Returncode is $($ReturnFromEXE.ExitCode)" 34 | 35 | if(!($ReturnFromEXE.ExitCode -eq $SuccessfulReturnCode)) { 36 | throw "$Executable failed with code $($ReturnFromEXE.ExitCode)" 37 | } 38 | } 39 | Function Convert-Subnet 40 | { 41 | <# 42 | .SYNOPSIS 43 | Converts between PrefixLength and subnet mask. 44 | 45 | 46 | .DESCRIPTION 47 | This script converts between PrefixLength and subnet mask parameters, these parameters define the size of a subnet for IPv4 addresses. 48 | This script assumes valid subnet mask input and does not support scenarios such as non-contiguous subnet masks. 49 | 50 | 51 | .INPUTS 52 | None 53 | 54 | .OUTPUTS 55 | The script outputs a PrefixLength if SubnetMask was entered, or a SubnetMask if a PrefixLength was entered. 56 | 57 | .NOTES 58 | Requires Windows 8 or later. 59 | 60 | #> 61 | 62 | [CmdletBinding(SupportsShouldProcess=$true)] 63 | 64 | Param( 65 | [Parameter(ParameterSetName="SubnetMask",Mandatory=$True)] 66 | [string] 67 | $SubnetMask, 68 | 69 | [Parameter(ParameterSetName="PrefixLength",Mandatory=$True)] 70 | [int] 71 | $PrefixLength 72 | ) 73 | 74 | #################################### 75 | #User provided a prefix 76 | if ($PrefixLength) 77 | { 78 | $PrefixLengthReturn = $PrefixLength 79 | if ($PrefixLength -gt 32) 80 | { 81 | Write-Warning "Invalid input, prefix length must be less than 32" 82 | exit(1) 83 | } 84 | 85 | $bitArray="" 86 | for($bitCount = 0; $PrefixLength -ne "0"; $bitCount++) 87 | { 88 | $bitArray += '1' 89 | $PrefixLength = $PrefixLength - 1; 90 | } 91 | 92 | #################################### 93 | #Fill in the rest with zeroes 94 | While ($bitCount -ne 32) 95 | { 96 | $bitArray += '0' 97 | $bitCount++ 98 | } 99 | #################################### 100 | #Convert the bit array into subnet mask 101 | $ClassAAddress = $bitArray.SubString(0,8) 102 | $ClassAAddress = [Convert]::ToUInt32($ClassAAddress, 2) 103 | $ClassBAddress = $bitArray.SubString(8,8) 104 | $ClassBAddress = [Convert]::ToUInt32($ClassBAddress, 2) 105 | $ClassCAddress = $bitArray.SubString(16,8) 106 | $ClassCAddress = [Convert]::ToUInt32($ClassCAddress, 2) 107 | $ClassDAddress = $bitArray.SubString(24,8) 108 | $ClassDAddress = [Convert]::ToUInt32($ClassDAddress, 2) 109 | 110 | $SubnetMaskReturn = "$ClassAAddress.$ClassBAddress.$ClassCAddress.$ClassDAddress" 111 | } 112 | 113 | #################################### 114 | ##User provided a subnet mask 115 | if ($SubnetMask) 116 | { 117 | #################################### 118 | #Ensure valid IP address input. Note this does not check for non-contiguous subnet masks! 119 | $Address=[System.Net.IPaddress]"0.0.0.0" 120 | Try 121 | { 122 | $IsValidInput=[System.Net.IPaddress]::TryParse($SubnetMask, [ref]$Address) 123 | } 124 | Catch 125 | { 126 | 127 | } 128 | Finally 129 | { 130 | 131 | } 132 | 133 | if ($IsValidInput -eq $False) 134 | { 135 | Write-Warning "Invalid Input. Please enter a properly formatted subnet mask." 136 | Exit(1) 137 | } 138 | 139 | #################################### 140 | #Convert subnet mask to prefix length 141 | If($IsValidInput) 142 | { 143 | $PrefixArray=@() 144 | $PrefixLength = 0 145 | $ByteArray = $SubnetMask.Split(".") 146 | 147 | #################################### 148 | #This loop converts the bytes to bits, add zeroes when necessary 149 | for($byteCount = 0; $byteCount-lt 4; $byteCount++) 150 | { 151 | $bitVariable = $ByteArray[$byteCount] 152 | $bitVariable = [Convert]::ToString($bitVariable, 2) 153 | 154 | if($bitVariable.Length -lt 8) 155 | { 156 | $NumOnes=$bitVariable.Length 157 | $NumZeroes=8-$bitVariable.Length 158 | 159 | for($bitCount=0; $bitCount -lt $NumZeroes; $bitCount++) 160 | { 161 | $Temp=$Temp+"0" 162 | } 163 | 164 | $bitVariable=$Temp+$bitVariable 165 | } 166 | 167 | #################################### 168 | #This loop counts the bits in the prefix 169 | for($bitCount=0; $bitCount -lt 8; $bitCount++) 170 | { 171 | if ($bitVariable[$bitCount] -eq "1") 172 | { 173 | $PrefixLength++ 174 | } 175 | 176 | $PrefixArray=$PrefixArray + ($bitVariable[$bitCount]) 177 | 178 | } 179 | } 180 | 181 | #################################### 182 | #Check if the subnet mask was contiguous, fail if it wasn't. 183 | $Mark=$False 184 | 185 | foreach ($bit in $PrefixArray) 186 | { 187 | if($bit -eq "0") 188 | { 189 | if($Mark -eq $False) 190 | { 191 | $Mark=$True 192 | } 193 | } 194 | if($bit -eq "1") 195 | { 196 | if($Mark -eq $True) 197 | { 198 | Write-Warning "Invalid Input. Please enter a properly formatted subnet mask." 199 | Exit(1) 200 | } 201 | } 202 | 203 | } 204 | 205 | $SubnetMaskReturn = $SubnetMask 206 | $PrefixLengthReturn = $PrefixLength 207 | } 208 | } 209 | ##Create the object to be returned to the console 210 | $Return = new-object Object 211 | Add-Member -InputObject $Return -Name PrefixLength -Value $PrefixLengthReturn -Type NoteProperty 212 | Add-Member -InputObject $Return -Name SubnetMask -Value $SubnetMaskReturn -Type NoteProperty 213 | $Return 214 | } 215 | Function Compress-VIADeDupDrive 216 | { 217 | [CmdletBinding(SupportsShouldProcess=$true)] 218 | Param( 219 | $DriveLetter 220 | ) 221 | Foreach($Item in $DriveLetter){ 222 | $Drive = $DriveLetter + ":" 223 | Start-DedupJob $Drive -Type Optimization -Priority High -Memory 75 -Wait 224 | Start-DedupJob $Drive -Type GarbageCollection -Priority High -Memory 75 -Wait 225 | Start-DedupJob $Drive -Type Scrubbing -Priority High -Memory 75 -Wait 226 | } 227 | } 228 | Function Enable-VIACredSSP 229 | { 230 | [CmdletBinding(SupportsShouldProcess=$true)] 231 | Param 232 | ( 233 | [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] 234 | $Connection 235 | ) 236 | 237 | #Enable CredSSP on Client 238 | Enable-WSManCredSSP -Role Client -DelegateComputer $Connection -Force -ErrorAction Stop 239 | Set-Item WSMan:\localhost\Client\AllowUnencrypted -Value $true -Force 240 | Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force -Concatenate 241 | } 242 | Function Get-VIAOSVersion 243 | { 244 | [CmdletBinding(SupportsShouldProcess=$true)] 245 | Param( 246 | ) 247 | $OS = Get-WmiObject -Class Win32_OperatingSystem 248 | $OSversion = [System.Environment]::OSVersion.Version 249 | $OSversionComplete = "$($version.major).$($version.Minor).$($version.build)" 250 | $OSversionMajorMinor = "$($version.major).$($version.Minor)" 251 | $OSversionMajor = "$($version.major).$($version.Minor)" 252 | 253 | 254 | Switch ($OSversionMajor) 255 | { 256 | "6.1" 257 | { 258 | If($OS.ProductType -eq 1){$OSv = "W7"}Else{$OSv = "WS2008R2"} 259 | } 260 | "6.2" 261 | { 262 | If($OS.ProductType -eq 1){$OSv = "W8"}Else{$OSv = "WS2012"} 263 | } 264 | "6.3" 265 | { 266 | If($OS.ProductType -eq 1){$OSv = "W81"}Else{$OSv = "WS2012R2"} 267 | } 268 | "10.0" 269 | { 270 | If($OS.ProductType -eq 1){$OSv = "W10"}Else{$OSv = "WS2016"} 271 | } 272 | DEFAULT {$OSv="Unknown"} 273 | } 274 | Return $OSV 275 | } 276 | Function Install-VIASNMP 277 | { 278 | [CmdletBinding(SupportsShouldProcess=$true)] 279 | 280 | Param( 281 | $ComputerName 282 | ) 283 | Foreach($Item in $ComputerName){ 284 | Invoke-Command -ComputerName $Item -ScriptBlock { 285 | Add-WindowsFeature -Name SNMP-Service -IncludeAllSubFeature -IncludeManagementTools 286 | } 287 | } 288 | } 289 | Function Install-VIADCB 290 | { 291 | [CmdletBinding(SupportsShouldProcess=$true)] 292 | 293 | Param( 294 | $ComputerName 295 | ) 296 | Foreach($Item in $ComputerName){ 297 | Invoke-Command -ComputerName $Item -ScriptBlock { 298 | Add-WindowsFeature -Name Data-Center-Bridging -IncludeAllSubFeature -IncludeManagementTools 299 | } 300 | } 301 | } 302 | Function Restart-VIAComputer 303 | { 304 | [CmdletBinding(SupportsShouldProcess=$true)] 305 | 306 | Param( 307 | $ComputerName 308 | ) 309 | Foreach($Item in $ComputerName){ 310 | Restart-Computer -ComputerName $ComputerName -Force -AsJob 311 | } 312 | } 313 | Function Show-VIAText 314 | { 315 | [CmdletBinding(SupportsShouldProcess=$true)] 316 | 317 | Param( 318 | $Text, 319 | $Color 320 | ) 321 | 322 | Write-Host $Text -ForegroundColor $Color 323 | } 324 | Function New-VIARandomPassword 325 | { 326 | [CmdletBinding(SupportsShouldProcess=$true)] 327 | 328 | Param( 329 | [int]$PasswordLength, 330 | [boolean]$Complex 331 | ) 332 | 333 | #Characters to use based 334 | $strSimple = "A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z” 335 | $strComplex = "A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z”,"!","_" 336 | $strNumbers = "2","3","4","5","6","7","8","9","0" 337 | 338 | #Check to see if password contains at least 1 digit 339 | $bolHasNumber = $false 340 | $pass = $null 341 | 342 | #Sets which Character Array to use based on $Complex 343 | if ($Complex){$strCharacters = $strComplex}else{$strCharacters = $strSimple} 344 | 345 | #Loop to actually generate the password 346 | for ($i=0;$i -lt $PasswordLength; $i++){$c = Get-Random -InputObject $strCharacters 347 | if ([char]::IsDigit($c)){$bolHasNumber = $true}$pass += $c} 348 | 349 | #Check to see if a Digit was seen, if not, fixit 350 | if ($bolHasNumber) 351 | { 352 | return $pass 353 | } 354 | else 355 | { 356 | $pos = Get-Random -Maximum $PasswordLength 357 | $n = Get-Random -InputObject $strNumbers 358 | $pwArray = $pass.ToCharArray() 359 | $pwArray[$pos] = $n 360 | $pass = "" 361 | foreach ($s in $pwArray) 362 | { 363 | $pass += $s 364 | } 365 | return $pass 366 | } 367 | } 368 | Function Update-VIALog 369 | { 370 | [CmdletBinding(SupportsShouldProcess=$true)] 371 | 372 | Param( 373 | [Parameter( 374 | Mandatory=$true, 375 | ValueFromPipeline=$true, 376 | ValueFromPipelineByPropertyName=$true, 377 | Position=0 378 | )] 379 | [string]$Data, 380 | 381 | [Parameter( 382 | Mandatory=$false, 383 | ValueFromPipeline=$true, 384 | ValueFromPipelineByPropertyName=$true, 385 | Position=0 386 | )] 387 | [string]$Solution = $Solution, 388 | 389 | [Parameter( 390 | Mandatory=$false, 391 | ValueFromPipeline=$true, 392 | ValueFromPipelineByPropertyName=$true, 393 | Position=1 394 | )] 395 | [validateset('Information','Warning','Error')] 396 | [string]$Class = "Information" 397 | 398 | ) 399 | $LogString = "$Solution, $Data, $Class, $(Get-Date)" 400 | $HostString = "$Solution, $Data, $(Get-Date)" 401 | 402 | Add-Content -Path $LogPath -Value $LogString 403 | switch ($Class) 404 | { 405 | 'Information'{ 406 | Write-Host $HostString -ForegroundColor Gray 407 | } 408 | 'Warning'{ 409 | Write-Host $HostString -ForegroundColor Yellow 410 | } 411 | 'Error'{ 412 | Write-Host $HostString -ForegroundColor Red 413 | } 414 | Default {} 415 | } 416 | } 417 | Function Suspend-VIAScript 418 | { 419 | [CmdletBinding(SupportsShouldProcess=$true)] 420 | 421 | Param( 422 | $Message = "Press any key to continue . . . " 423 | ) 424 | 425 | If ($psISE) { 426 | # The "ReadKey" functionality is not supported in Windows PowerShell ISE. 427 | $Shell = New-Object -ComObject "WScript.Shell" 428 | $Button = $Shell.Popup("Click OK to continue.", 0, "Script Paused", 0) 429 | Return 430 | } 431 | 432 | Write-Host -NoNewline $Message 433 | $Ignore = 434 | 16, # Shift (left or right) 435 | 17, # Ctrl (left or right) 436 | 18, # Alt (left or right) 437 | 20, # Caps lock 438 | 91, # Windows key (left) 439 | 92, # Windows key (right) 440 | 93, # Menu key 441 | 144, # Num lock 442 | 145, # Scroll lock 443 | 166, # Back 444 | 167, # Forward 445 | 168, # Refresh 446 | 169, # Stop 447 | 170, # Search 448 | 171, # Favorites 449 | 172, # Start/Home 450 | 173, # Mute 451 | 174, # Volume Down 452 | 175, # Volume Up 453 | 176, # Next Track 454 | 177, # Previous Track 455 | 178, # Stop Media 456 | 179, # Play 457 | 180, # Mail 458 | 181, # Select Media 459 | 182, # Application 1 460 | 183 # Application 2 461 | 462 | While ($KeyInfo.VirtualKeyCode -Eq $Null -Or $Ignore -Contains $KeyInfo.VirtualKeyCode) { 463 | $KeyInfo = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown") 464 | } 465 | 466 | Write-Host 467 | } 468 | Function Clear-VIAVolume 469 | { 470 | [cmdletbinding(SupportsShouldProcess=$True)] 471 | 472 | Param( 473 | $VolumeLabel 474 | ) 475 | Get-Volume -FileSystemLabel $VolumeLabel -ErrorAction SilentlyContinue| Get-Partition | Get-Disk | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false 476 | } 477 | Function Start-VIASoundNotify 478 | { 479 | 480 | [cmdletbinding(SupportsShouldProcess=$True)] 481 | 482 | Param( 483 | ) 484 | 485 | $sound = new-Object System.Media.SoundPlayer; 486 | $sound.SoundLocation="c:\WINDOWS\Media\notify.wav"; 487 | $sound.Play(); 488 | } 489 | Function Wait-VIAServiceToRun 490 | { 491 | [cmdletbinding(SupportsShouldProcess=$True)] 492 | Param( 493 | $ServiceName = 'LanmanWorkstation', 494 | $VMname, 495 | $Credentials 496 | ) 497 | Write-Verbose "Waiting for $ServiceName to start on $VMname" 498 | Invoke-Command -VMName $VMname -ScriptBlock { 499 | Param($ServiceName) 500 | do{ 501 | Write-Verbose "Waiting for $ServiceName to start" 502 | Get-Service -Name $ServiceName 503 | }until((Get-Service -Name $ServiceName).Status -eq 'Running' ) 504 | } -Credential $Credentials -ArgumentList $ServiceName 505 | } 506 | 507 | -------------------------------------------------------------------------------- /VIAXMLUtility.psm1: -------------------------------------------------------------------------------- 1 | Function Get-VIAXMLData 2 | { 3 | [cmdletbinding(SupportsShouldProcess=$True)] 4 | 5 | Param( 6 | $RootFolder = $RootFolder 7 | ) 8 | 9 | $Classes = 'Customers','CommonSettings','ProductKeys','Networks','Domains','Servers','Roles','Services' 10 | 11 | $XMLData = @() 12 | $XMLData += foreach($Item in $Classes){ 13 | 14 | #Read data from XML 15 | $SettingsFile = $RootFolder + "\" + $Item + ".xml" 16 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 17 | } 18 | 19 | $Return = $XMLData 20 | } 21 | Function Get-VIAXMLFabricData 22 | { 23 | [cmdletbinding(SupportsShouldProcess=$True)] 24 | 25 | Param( 26 | [ValidateSet('Customers','CommonSettings','ProductKeys','Networks','Domains','Servers','Certificates','VHDs','Roles','Services')] 27 | $Class, 28 | 29 | [switch]$Active, 30 | 31 | $SettingsFile = $SettingsFile 32 | ) 33 | 34 | #Read data from XML 35 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 36 | switch ($Class) 37 | { 38 | 'Customers'{ 39 | $XMLData = $Settings.FABRIC.Customers.Customer 40 | } 41 | 'CommonSettings'{ 42 | $XMLData = $Settings.FABRIC.CommonSettings.CommonSetting 43 | } 44 | 'ProductKeys'{ 45 | $XMLData = $Settings.FABRIC.ProductKeys.ProductKey 46 | } 47 | 'Networks'{ 48 | $XMLData = $Settings.FABRIC.Networks.Network 49 | } 50 | 'Domains'{ 51 | $XMLData = $Settings.FABRIC.Domains.Domain 52 | } 53 | 'Servers'{ 54 | $XMLData = $Settings.FABRIC.Servers.Server 55 | } 56 | 'BuildServers'{ 57 | $XMLData = $Settings.FABRIC.BuildServers.BuildServer 58 | } 59 | 'Certificates'{ 60 | $XMLData = $Settings.FABRIC.Certificates.Certificate 61 | } 62 | 'VHDs'{ 63 | $XMLData = $Settings.FABRIC.VHDs.VHD 64 | } 65 | 'Roles'{ 66 | $XMLData = $Settings.FABRIC.Roles.Role 67 | } 68 | 'Services'{ 69 | $XMLData = $Settings.FABRIC.Services.Service 70 | } 71 | Default { 72 | $XMLData = $Settings.FABRIC 73 | } 74 | } 75 | $Return = $XMLData 76 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 77 | } 78 | Function Get-VIAXMLFabricCustomer 79 | { 80 | [cmdletbinding(SupportsShouldProcess=$True)] 81 | 82 | Param( 83 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 84 | $id, 85 | 86 | [Parameter(Position=1,Mandatory=$false)] 87 | $SettingsFile = $SettingsFile, 88 | 89 | [Parameter(Position=1,Mandatory=$false)] 90 | [switch]$Active 91 | ) 92 | 93 | #Read data from XML 94 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 95 | $XMLData = $Settings.FABRIC.Customers.Customer | Where-Object Id -EQ $id 96 | 97 | $Item = $XMLData 98 | $Data = [ordered]@{ 99 | Id = $Item.id 100 | Name = $Item.Name 101 | Contact = $Item.Contact 102 | OptionalData = $Item.OptionalData 103 | Active = $Item.Active 104 | } 105 | $Return = New-Object -TypeName psobject -Property $Data 106 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 107 | } 108 | Function Get-VIAXMLFabricCommonSetting 109 | { 110 | [cmdletbinding(SupportsShouldProcess=$True)] 111 | 112 | Param( 113 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 114 | $id, 115 | 116 | [Parameter(Position=1,Mandatory=$false)] 117 | $SettingsFile = $SettingsFile, 118 | 119 | [Parameter(Position=1,Mandatory=$false)] 120 | [switch]$Active 121 | ) 122 | 123 | #Read data from XML 124 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 125 | $XMLData = $Settings.FABRIC.CommonSettings.CommonSetting | Where-Object Id -EQ $id 126 | 127 | $Item = $XMLData 128 | $Data = [ordered]@{ 129 | id = $item.id 130 | Name = $item.Name 131 | Active = $Item.Active 132 | MajorVersion = $Item.MajorVersion 133 | MinorVersion = $Item.MinorVersion 134 | Solution = $Item.Solution 135 | CodeName = $Item.CodeName 136 | LocalPassword = $Item.LocalName 137 | OrgName = $Item.OrgName 138 | FullName = $Item.FullName 139 | TimeZoneName = $Item.TimeZoneName 140 | InputLocale = $Item.InputLocale 141 | SystemLocale = $Item.SystemLocale 142 | UILanguage = $Item.UILanguage 143 | UserLocale = $Item.UserLocale 144 | VMSwitchName = $Item.VMSwitchName 145 | WorkgroupName = $Item.WorkgroupName 146 | VHDSize = $Item.VHDSize 147 | OptionalData = $Item.OptionalData 148 | PasswordUpdated = $Item.PasswordUpdated 149 | } 150 | $Return = New-Object -TypeName psobject -Property $Data 151 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 152 | } 153 | Function Get-VIAXMLFabricProductKey 154 | { 155 | [cmdletbinding(SupportsShouldProcess=$True)] 156 | 157 | Param( 158 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 159 | $id, 160 | 161 | [Parameter(Position=1,Mandatory=$false)] 162 | $SettingsFile = $SettingsFile, 163 | 164 | [Parameter(Position=1,Mandatory=$false)] 165 | [switch]$Active 166 | ) 167 | 168 | #Read data from XML 169 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 170 | $XMLData = $Settings.FABRIC.ProductKeys.ProductKey | Where-Object Id -EQ $id 171 | 172 | $Return = foreach($Item in $XMLData){ 173 | $Data = [ordered]@{ 174 | Id = $Item.Id; 175 | Name = $Item.Name; 176 | Key = $Item.Key; 177 | Active = $Item.Active; 178 | } 179 | New-Object -TypeName psobject -Property $Data 180 | } 181 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 182 | } 183 | Function Get-VIAXMLFabricNetwork 184 | { 185 | [cmdletbinding(SupportsShouldProcess=$True)] 186 | 187 | Param( 188 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 189 | $id, 190 | 191 | [Parameter(Position=1,Mandatory=$false)] 192 | $SettingsFile = $SettingsFile, 193 | 194 | [Parameter(Position=1,Mandatory=$false)] 195 | [switch]$Active 196 | ) 197 | 198 | #Read data from XML 199 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 200 | $XMLData = $Settings.FABRIC.Networks.Network | Where-Object Id -EQ $id 201 | 202 | $Return = foreach($Item in $XMLData){ 203 | $Data = [ordered]@{ 204 | id = $item.id 205 | Name = $item.Name 206 | NetIP = $item.NetIP 207 | Gateway = $item.Gateway 208 | DNS = $item.DNS 209 | SubNet = $item.SubNet 210 | VMMStart = $item.VMMStart 211 | VMMEnd = $item.VMMEnd 212 | VMMReserv = $item.VMMReserv 213 | DHCPStart = $item.DHCPStart 214 | DHCPEnd = $item.DHCPEnd 215 | DHCPReserv = $item.DHCPReserv 216 | VLAN = $item.VLAN 217 | RDNS = $item.RDNS 218 | OptionalData = $item.OptionalData 219 | Active = $item.Active 220 | } 221 | New-Object -TypeName psobject -Property $Data 222 | } 223 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 224 | } 225 | Function Get-VIAXMLFabricDomain 226 | { 227 | [cmdletbinding(SupportsShouldProcess=$True)] 228 | 229 | Param( 230 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 231 | $id, 232 | 233 | [Parameter(Position=1,Mandatory=$false)] 234 | $SettingsFile = $SettingsFile, 235 | 236 | [Parameter(Position=1,Mandatory=$false)] 237 | [switch]$Active 238 | ) 239 | 240 | #Read data from XML 241 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 242 | $XMLData = $Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id 243 | 244 | $Item = $XMLData 245 | $Data = [ordered]@{ 246 | id = $item.id 247 | Name = $item.Name 248 | DNSDomain = $item.DNSDomain 249 | DNSDomainExternal = $item.DNSDomainExternal 250 | DomainNetBios = $item.DomainNetBios 251 | DomainAdmin = $item.DomainAdmin 252 | DomainAdminPassword = $item.DomainAdminPassword 253 | DomainAdminDomain = $item.DomainAdminDomain 254 | DomainDS = $item.DomainDS 255 | BaseOU = $item.BaseOU 256 | MachienObjectOU = $item.MachienObjectOU 257 | SiteName = $item.SiteName 258 | OptionalData = $item.OptionalData 259 | Active = $item.Active 260 | } 261 | $Return = New-Object -TypeName psobject -Property $Data 262 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 263 | } 264 | Function Get-VIAXMLFabricDomainOU 265 | { 266 | [cmdletbinding(SupportsShouldProcess=$True)] 267 | 268 | Param( 269 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 270 | $id, 271 | 272 | [Parameter(Position=1,Mandatory=$false)] 273 | $SettingsFile = $SettingsFile, 274 | 275 | [Parameter(Position=2,Mandatory=$false)] 276 | [switch]$Active 277 | ) 278 | 279 | #Read data from XML 280 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 281 | $ParentItem = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id) 282 | $Items = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id).DomainOUs.DomainOU 283 | foreach($Item in $Items){ 284 | $Data = [ordered]@{ 285 | Name = $item.Name; 286 | Path = $item.Path; 287 | ParentID = $ParentItem.Id; 288 | ParentName = $ParentItem.Name; 289 | Active = $item.Active; 290 | } 291 | $Return = New-Object -TypeName psobject -Property $Data 292 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 293 | } 294 | } 295 | Function Get-VIAXMLFabricDomainAccount 296 | { 297 | [cmdletbinding(SupportsShouldProcess=$True)] 298 | 299 | Param( 300 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 301 | $id, 302 | 303 | [Parameter(Position=1,Mandatory=$false)] 304 | $SettingsFile = $SettingsFile, 305 | 306 | [Parameter(Position=2,Mandatory=$false)] 307 | [switch]$Active 308 | ) 309 | 310 | #Read data from XML 311 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 312 | $ParentItem = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id) 313 | $Items = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id).DomainAccounts.DomainAccount 314 | foreach($Item in $Items){ 315 | $Data = [ordered]@{ 316 | Name = $item.Name; 317 | AccountDescription = $item.AccountDescription; 318 | OUName = $item.OUName; 319 | AccountType = $item.AccountType; 320 | MemberOf = $item.MemberOf 321 | ParentID = $ParentItem.Id; 322 | ParentName = $ParentItem.Name; 323 | Active = $item.Active; 324 | } 325 | $Return = New-Object -TypeName psobject -Property $Data 326 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 327 | } 328 | } 329 | Function Get-VIAXMLFabricDomainGroup 330 | { 331 | [cmdletbinding(SupportsShouldProcess=$True)] 332 | 333 | Param( 334 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 335 | $id, 336 | 337 | [Parameter(Position=1,Mandatory=$false)] 338 | $SettingsFile = $SettingsFile, 339 | 340 | [Parameter(Position=2,Mandatory=$false)] 341 | [switch]$Active 342 | ) 343 | 344 | #Read data from XML 345 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 346 | $ParentItem = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id) 347 | $Items = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id).DomainGroups.DomainGroup 348 | foreach($Item in $Items){ 349 | $Data = [ordered]@{ 350 | Name = $item.Name; 351 | Description = $item.Description; 352 | DomainOU = $item.DomainOU; 353 | GroupScope = $item.GroupScope; 354 | ParentID = $ParentItem.Id; 355 | ParentName = $ParentItem.Name; 356 | Active = $item.Active; 357 | } 358 | $Return = New-Object -TypeName psobject -Property $Data 359 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 360 | } 361 | } 362 | Function Get-VIAXMLFabricDomainCertificate 363 | { 364 | [cmdletbinding(SupportsShouldProcess=$True)] 365 | 366 | Param( 367 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 368 | $id, 369 | 370 | [Parameter(Position=1,Mandatory=$false)] 371 | $SettingsFile = $SettingsFile, 372 | 373 | [Parameter(Position=2,Mandatory=$false)] 374 | [switch]$Active 375 | ) 376 | 377 | #Read data from XML 378 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 379 | $ParentItem = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id) 380 | $Items = ($Settings.FABRIC.Domains.Domain | Where-Object Id -EQ $id).Certificates.Certificate 381 | foreach($Item in $Items){ 382 | $Data = [ordered]@{ 383 | Name = $item.Name; 384 | Description = $item.Description; 385 | Path = $item.Path; 386 | Destination = $item.Destination; 387 | PW = $item.PW; 388 | ParentID = $ParentItem.Id; 389 | ParentName = $ParentItem.Name; 390 | Active = $item.Active; 391 | } 392 | $Return = New-Object -TypeName psobject -Property $Data 393 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 394 | } 395 | } 396 | Function Get-VIAXMLFabricServer 397 | { 398 | [cmdletbinding(SupportsShouldProcess=$True)] 399 | 400 | Param( 401 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 402 | $id, 403 | 404 | [Parameter(Position=1,Mandatory=$false)] 405 | $SettingsFile = $SettingsFile, 406 | 407 | [Parameter(Position=2,Mandatory=$false)] 408 | [switch]$Active 409 | ) 410 | 411 | #Read data from XML 412 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 413 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 414 | foreach($Item in $Items){ 415 | $Data = [ordered]@{ 416 | id = $Item.id 417 | Name = $Item.Name 418 | ComputerName = $Item.ComputerName 419 | Deploy = $Item.Deploy 420 | DeployOrder = $Item.DeployOrder 421 | WaitForDeployment = $Item.WaitForDeployment 422 | Virtual = $Item.Virtual 423 | Memory = $Item.Memory 424 | CPUCount = $Item.CPUCount 425 | DiffOrCreate = $Item.DiffOrCreate 426 | Type = $Item.Type 427 | Version = $Item.Version 428 | Edition = $Item.Edition 429 | UI = $Item.UI 430 | DomainJoined = $Item.DomainJoined 431 | MachineObjectOU = $Item.MachineObjectOU 432 | OOBName = $Item.OOBName 433 | OOBIPAddress = $Item.OOBIPAddress 434 | OOBSubnetMask = $Item.OOBSubnetMask 435 | OOBDefaultGateway = $Item.OOBDefaultGateway 436 | OOBVLANID = $Item.OOBVLANID 437 | Path = $item.Path 438 | Active = $item.Active 439 | } 440 | $Return = New-Object -TypeName psobject -Property $Data 441 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 442 | } 443 | } 444 | Function Get-VIAXMLFabricServerRole 445 | { 446 | [cmdletbinding(SupportsShouldProcess=$True)] 447 | 448 | Param( 449 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 450 | $id, 451 | 452 | [Parameter(Position=1,Mandatory=$false)] 453 | $SettingsFile = $SettingsFile, 454 | 455 | [Parameter(Position=2,Mandatory=$false)] 456 | [switch]$Active 457 | ) 458 | 459 | #Read data from XML 460 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 461 | $ParentItem = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 462 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id).Roles.Role 463 | foreach($Item in $Items){ 464 | $Data = [ordered]@{ 465 | Name = $item.Name; 466 | RoleUUID = $item.RoleUUID; 467 | ParentID = $ParentItem.Id; 468 | ParentName = $ParentItem.Name; 469 | Active = $item.Active; 470 | } 471 | $Return = New-Object -TypeName psobject -Property $Data 472 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 473 | } 474 | } 475 | Function Get-VIAXMLFabricServerOptionalSetting 476 | { 477 | [cmdletbinding(SupportsShouldProcess=$True)] 478 | 479 | Param( 480 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 481 | $id, 482 | 483 | [Parameter(Position=1,Mandatory=$false)] 484 | $SettingsFile = $SettingsFile, 485 | 486 | [Parameter(Position=2,Mandatory=$false)] 487 | [switch]$Active 488 | ) 489 | 490 | #Read data from XML 491 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 492 | $ParentItem = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 493 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id).OptionalSettings.OptionalSetting 494 | foreach($Item in $Items){ 495 | $Data = [ordered]@{ 496 | Name = $item.Name; 497 | Data = $item.Data; 498 | ParentID = $ParentItem.Id; 499 | ParentName = $ParentItem.Name; 500 | Active = $item.Active; 501 | } 502 | $Return = New-Object -TypeName psobject -Property $Data 503 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 504 | } 505 | } 506 | Function Get-VIAXMLFabricServerNetworkadapter 507 | { 508 | [cmdletbinding(SupportsShouldProcess=$True)] 509 | 510 | Param( 511 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 512 | $id, 513 | 514 | [Parameter(Position=1,Mandatory=$false)] 515 | $SettingsFile = $SettingsFile, 516 | 517 | [Parameter(Position=2,Mandatory=$false)] 518 | [switch]$Active 519 | ) 520 | 521 | #Read data from XML 522 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 523 | $ParentItem = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 524 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id).Networkadapters.Networkadapter 525 | foreach($Item in $Items){ 526 | $Data = [ordered]@{ 527 | Name = $item.Name; 528 | MACAddress = $item.MACAddress; 529 | IPAddress = $item.IPAddress; 530 | DefaultGateway = $item.DefaultGateway; 531 | PrefixLength = $item.PrefixLength; 532 | DNS = $item.DNS; 533 | ConnectedToNetwork = $item.ConnectedToNetwork; 534 | ParentID = $ParentItem.Id; 535 | ParentName = $ParentItem.Name; 536 | Active = $item.Active; 537 | } 538 | $Return = New-Object -TypeName psobject -Property $Data 539 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 540 | } 541 | } 542 | Function Get-VIAXMLFabricServerNetworkTeam 543 | { 544 | [cmdletbinding(SupportsShouldProcess=$True)] 545 | 546 | Param( 547 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 548 | $id, 549 | 550 | [Parameter(Position=1,Mandatory=$false)] 551 | $SettingsFile = $SettingsFile, 552 | 553 | [Parameter(Position=2,Mandatory=$false)] 554 | [switch]$Active 555 | ) 556 | 557 | #Read data from XML 558 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 559 | $ParentItem = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 560 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id).NetworkTeams.NetworkTeam 561 | foreach($Item in $Items){ 562 | $Data = [ordered]@{ 563 | Name = $item.Name; 564 | Member = $item.Member; 565 | ParentID = $ParentItem.Id; 566 | ParentName = $ParentItem.Name; 567 | Active = $item.Active; 568 | } 569 | $Return = New-Object -TypeName psobject -Property $Data 570 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 571 | } 572 | } 573 | Function Get-VIAXMLFabricServerDataDisk 574 | { 575 | [cmdletbinding(SupportsShouldProcess=$True)] 576 | 577 | Param( 578 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 579 | $id, 580 | 581 | [Parameter(Position=1,Mandatory=$false)] 582 | $SettingsFile = $SettingsFile, 583 | 584 | [Parameter(Position=2,Mandatory=$false)] 585 | [switch]$Active 586 | ) 587 | 588 | #Read data from XML 589 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 590 | $ParentItem = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id) 591 | $Items = ($Settings.FABRIC.Servers.Server | Where-Object Id -EQ $id).DataDisks.DataDisk 592 | foreach($Item in $Items){ 593 | $Data = [ordered]@{ 594 | Name = $item.Name; 595 | DiskNumber = $item.DiskNumber; 596 | DiskSize = $item.DiskSize; 597 | FileSystem = $item.FileSystem; 598 | PartitionType = $item.PartitionType; 599 | ParentID = $ParentItem.Id; 600 | ParentName = $ParentItem.Name; 601 | Active = $item.Active; 602 | } 603 | $Return = New-Object -TypeName psobject -Property $Data 604 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 605 | } 606 | } 607 | Function Get-VIAXMLFabricVHD 608 | { 609 | [cmdletbinding(SupportsShouldProcess=$True)] 610 | 611 | Param( 612 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 613 | $id, 614 | 615 | [Parameter(Position=1,Mandatory=$false)] 616 | $SettingsFile = $SettingsFile, 617 | 618 | [Parameter(Position=2,Mandatory=$false)] 619 | [switch]$Active 620 | ) 621 | 622 | #Read data from XML 623 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 624 | $ParentItem = ($Settings.FABRIC | Where-Object Id -EQ $id) 625 | $Items = ($Settings.FABRIC.VHDs.VHD | Where-Object Id -EQ $id) 626 | foreach($Item in $Items){ 627 | $Data = [ordered]@{ 628 | id = $item.id; 629 | Name = $item.Name; 630 | Type = $item.Type; 631 | Version = $item.Version; 632 | Edition = $item.Edition; 633 | UI = $item.UI; 634 | Location = $item.Location; 635 | License = $item.License; 636 | OptionalData = $item.OptionalData; 637 | ParentID = $ParentItem.Id; 638 | ParentName = $ParentItem.Name; 639 | Active = $item.Active; 640 | } 641 | $Return = New-Object -TypeName psobject -Property $Data 642 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 643 | } 644 | } 645 | Function Get-VIAXMLFabricRoles 646 | { 647 | [cmdletbinding(SupportsShouldProcess=$True)] 648 | 649 | Param( 650 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 651 | $id, 652 | 653 | [Parameter(Position=1,Mandatory=$false)] 654 | $SettingsFile = $SettingsFile, 655 | 656 | [Parameter(Position=2,Mandatory=$false)] 657 | [switch]$Active 658 | ) 659 | 660 | #Read data from XML 661 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 662 | $ParentItem = ($Settings.FABRIC | Where-Object Id -EQ $id) 663 | $Items = ($Settings.FABRIC.Roles.Role | Where-Object Id -EQ $id) 664 | foreach($Item in $Items){ 665 | $Data = [ordered]@{ 666 | id = $item.id; 667 | Name = $item.Name; 668 | Description = $item.Description; 669 | Config = [array]$item.Config.SelectNodes("*"); 670 | ParentID = $ParentItem.Id; 671 | ParentName = $ParentItem.Name; 672 | Active = $item.Active; 673 | } 674 | $Return = New-Object -TypeName psobject -Property $Data 675 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 676 | } 677 | } 678 | Function Get-VIAXMLFabricServices 679 | { 680 | [cmdletbinding(SupportsShouldProcess=$True)] 681 | 682 | Param( 683 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 684 | $id, 685 | 686 | [Parameter(Position=1,Mandatory=$false)] 687 | $SettingsFile = $SettingsFile, 688 | 689 | [Parameter(Position=2,Mandatory=$false)] 690 | [switch]$Active 691 | ) 692 | 693 | #Read data from XML 694 | [xml]$Settings = Get-Content $SettingsFile -ErrorAction Stop 695 | $ParentItem = ($Settings.FABRIC | Where-Object Id -EQ $id) 696 | $Items = ($Settings.FABRIC.Services.Service | Where-Object Id -EQ $id) 697 | foreach($Item in $Items){ 698 | $Data = [ordered]@{ 699 | id = $item.id; 700 | Name = $item.Name; 701 | Description = $item.Description; 702 | HA = $item.HA; 703 | Config = [array]$item.Config.SelectNodes("*"); 704 | ParentID = $ParentItem.Id; 705 | ParentName = $ParentItem.Name; 706 | Active = $item.Active; 707 | } 708 | $Return = New-Object -TypeName psobject -Property $Data 709 | if($Active -eq $true){$Return | Where-Object -Property Active -EQ -Value True}else{$Return} 710 | } 711 | } 712 | 713 | --------------------------------------------------------------------------------