├── .gitignore
├── README.md
├── .gitmodules
├── ActiveDirectory
├── Get-RecursiveGroupMembers.ps1
└── Get-NewADAccounts.ps1
├── VMware
├── Set-UpdateTools.ps1
├── Get-HostRAIDLevel.ps1
├── Export-RVTools.ps1
├── Enable-HotAdd.ps1
├── Export-VCSADatabase.ps1
├── Compare-VCRole.ps1
├── VMNoteSync.ps1
└── Set-PostDeployConfig.ps1
├── Server
├── Windows
│ ├── Invoke-WindowsUpdates.ps1
│ └── Enable-CleanMgr.ps1
├── DHCP
│ ├── Sync-DHCPScope.ps1
│ └── Invoke-DHCPMigration.ps1
└── Dell
│ └── Set-DRACConfig.ps1
├── Games
└── Get-SteamAchievements.ps1
├── Misc
├── Move-PhotoDate.ps1
└── Update-Readme.ps1
├── Profile
└── Microsoft.PowerShell_profile.ps1
├── Exchange
└── Start-MailSearch.ps1
└── _Tools
└── WmiExplorer.ps1
/.gitignore:
--------------------------------------------------------------------------------
1 | /.project
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sneddo/Powershell/HEAD/README.md
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "_Modules/PSReadLine"]
2 | path = _Modules/PSReadLine
3 | url = https://github.com/lzybkr/PSReadLine.git
4 |
--------------------------------------------------------------------------------
/ActiveDirectory/Get-RecursiveGroupMembers.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Get all members of AD group, and nested groups
4 |
5 | .DESCRIPTION
6 | Get all members of AD group, and nested groups
7 |
8 | .NOTES
9 | File Name : Get-RecursiveGroupMembers.ps1
10 | Author : John Sneddon
11 | Version : 1.0.0
12 |
13 | .REQUIREMENTS
14 | WinSCP
15 | #>
16 |
17 | function Get-RecursiveGroupMembers ($grp)
18 | {
19 | $grpMembers = Get-ADGroup $grp -properties members
20 | $tmpMembers =@()
21 |
22 | foreach ($member in $grpMembers.members)
23 | {
24 | $mem = Get-ADObject $member
25 |
26 | if ($mem.ObjectClass -eq "group")
27 | {
28 | $tmpMembers += Get-RecursiveGroupMembers $member
29 | }
30 | else
31 | {
32 | # user only
33 | $tmpMembers += $member
34 | }
35 | }
36 |
37 | $tmpMembers
38 | }
--------------------------------------------------------------------------------
/VMware/Set-UpdateTools.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Quick script to set VMware tools to update on reboot.
4 |
5 | .DESCRIPTION
6 | Sets all VMs in specified vCenter to update tools on reboot.
7 |
8 | .NOTES
9 | File Name : Set-UpdateTools.ps1
10 | Author : John Sneddon
11 | Version : 1.0
12 |
13 | .PARAMETER ComputerName
14 | Specify the vCenter server name
15 | #>
16 | param
17 | (
18 | [ValidateScript({Test-Connection $_ -Quiet -Count 1})]
19 | [string]$ComputerName
20 | )
21 |
22 | # Adding PowerCLI core snapin
23 | if (!(get-pssnapin -name VMware.VimAutomation.Core -erroraction silentlycontinue)) {
24 | add-pssnapin VMware.VimAutomation.Core
25 | }
26 |
27 |
28 | Connect-VIServer $ComputerName
29 |
30 | $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
31 | $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
32 | $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
33 |
34 | Foreach ($vm in (Get-View -ViewType VirtualMachine)) {
35 | $vm.ReconfigVM($vmConfigSpec)
36 | }
37 |
--------------------------------------------------------------------------------
/Server/Windows/Invoke-WindowsUpdates.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Invoke Windows update search and install
4 |
5 | .DESCRIPTION
6 | Runs an update check and install, with automatic reboot at the end if
7 | required.
8 |
9 | .NOTES
10 | File Name : Invoke-WindowsUpdates.ps1
11 | Author : John Sneddon
12 | Version : 1.0.0
13 | #>
14 |
15 | #Define update criteria.
16 | $Criteria = "IsInstalled=0 and Type='Software'"
17 |
18 | #Search for relevant updates.
19 | $Searcher = New-Object -ComObject Microsoft.Update.Searcher
20 | $SearchResult = $Searcher.Search($Criteria).Updates
21 |
22 | #Download updates.
23 | $Session = New-Object -ComObject Microsoft.Update.Session
24 | $Downloader = $Session.CreateUpdateDownloader()
25 | $Downloader.Updates = $SearchResult
26 | $Downloader.Download()
27 |
28 | #Install updates.
29 | $Installer = New-Object -ComObject Microsoft.Update.Installer
30 | $Installer.Updates = $SearchResult
31 | $Result = $Installer.Install()
32 |
33 | #Reboot if required by updates.
34 | If ($Result.rebootRequired) { shutdown.exe /t 0 /r }
--------------------------------------------------------------------------------
/VMware/Get-HostRAIDLevel.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Get the RAID config of all hosts
4 |
5 | .DESCRIPTION
6 | Get the RAID detail for ESX hosts
7 |
8 | .NOTES
9 | File Name : Get-HostRAIDLevel.ps1
10 | Author : John Sneddon
11 | Version : 1.0.0
12 | #>
13 | $timeout = 2
14 | $HostCred = Get-Credential
15 | $CIOpt = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 -UseSsl
16 |
17 | $VMH = Get-VMHost | Where {$_.PowerState -eq "PoweredOn" -and $_.ConnectionState -eq "Connected" }
18 |
19 | $i=0
20 | foreach ($h in $VMH)
21 | {
22 | $RAID = "CIM Error"
23 | Write-Progress -Activity "Fetching RAID detail" -status $h.name -percentcomplete ($i/($vmh.count))
24 | $Session = New-CimSession -Authentication Basic -Credential $HostCred -ComputerName $h.Name -port 443 -SessionOption $CIOpt -OperationTimeoutSec $timeout -ErrorAction SilentlyContinue 2>$null 3>$null
25 | if ($Session)
26 | {
27 | $RAID = Get-CimInstance -CimSession $Session -OperationTimeoutSec $timeout -ClassName CIM_StorageVolume -ErrorAction SilentlyContinue 2>$null 3>$null | Select -expandproperty ElementName
28 | }
29 | New-object PSObject -Property @{"Name" = $h.Name; "ESX"=$h.Version; "RAID" = $RAID }
30 | $i=$i+100
31 | }
32 | Write-Progress -Status "Done" -Activity "Done" -Completed
33 |
--------------------------------------------------------------------------------
/VMware/Export-RVTools.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Performs full export from RVTools
4 | .DESCRIPTION
5 | Performs full export from RVTools. Archives old versions.
6 | .NOTES
7 | File Name : RVToolsExport.ps1
8 | Author : John Sneddon
9 | Version : 1.0.1
10 | .PARAMETER Servers
11 | Specify which vCenter server(s) to connect to
12 | .PARAMETER BasePath
13 | Specify the path to export to. Server name and date appended.
14 | .PARAMETER OldFileDays
15 | How many days to retain copies
16 | #>
17 |
18 | param
19 | (
20 | $Servers = @("VCENTER"),
21 | $BasePath = "C:\Scripts\Powershell\RVToolsExport\Archive",
22 | $OldFileDays = 30
23 | )
24 |
25 | $Date = (Get-Date -f "yyyyMMdd")
26 |
27 | foreach ($Server in $Servers)
28 | {
29 | # Create Directory
30 | New-Item -Path "$BasePath\$Server\$Date" -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
31 |
32 | # Run Export
33 | . "C:\Program Files (x86)\RobWare\RVTools\RVTools.exe" -passthroughAuth -s $Server -c ExportAll2csv -d "$BasePath\$Server\$Date"
34 |
35 | # Cleanup old files
36 | $Items = Get-ChildItem -Directory "$BasePath\$server"
37 | foreach ($item in $items)
38 | {
39 | $itemDate = ("{0}/{1}/{2}" -f $item.name.Substring(6,2),$item.name.Substring(4,2),$item.name.Substring(0,4))
40 |
41 | if ((((Get-date).AddDays(-$OldFileDays))-(Get-Date($itemDate))).Days -gt 0)
42 | {
43 | $item | Remove-Item -Recurse
44 | }
45 | }
46 | }
47 |
48 | # Changelog:
49 | # 1.0.0 - Initial release
50 | # 1.0.1 - Fixed cleanup routine with uninitialised variable $path
51 |
--------------------------------------------------------------------------------
/Games/Get-SteamAchievements.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Grab achievement stats for a Steam account
4 |
5 | .DESCRIPTION
6 | Scrapes achievement data for a Steam profile. Must be set to public to work.
7 |
8 | .NOTES
9 | File Name : Get-SteamAchievements.ps1
10 | Author : John Sneddon
11 | Version : 1.0.0
12 | #>
13 |
14 | $User = Read-Host "Steam short name"
15 | $webclient = new-object System.Net.WebClient
16 | $GamesURLContent = $webclient.DownloadString("http://steamcommunity.com/id/{0}/games/?tab=all" -f $User)
17 |
18 | $Achieves = @()
19 |
20 | if ($GamesURLContent.Content -match "var rgGames = \[(.*)\]")
21 | {
22 | $Games = (ConvertFrom-Json ("[{0}]" -f $Matches[1])) | Where {$_.availStatLinks.achievements -and ($_.hours_forever -gt 0)}
23 |
24 | foreach ($Game in $Games)
25 | {
26 | $GameAchieveContent = Invoke-WebRequest ("http://steamcommunity.com/id/{0}/stats/{1}/?tab=achievements" -f $User, $Game.friendlyURL)
27 |
28 | if ($GameAchieveContent -match "([0-9]+) of ([0-9]+) \(([0-9]+)%\) achievements earned")
29 | {
30 | Write-Host ("{0} {1}/{2} ({3})" -f $Game.Name, $Matches[1], $Matches[2], $Matches[3])
31 | $Achieves += New-Object PSObject -Property @{"Name" = $Game.Name; "Completed" = [int]$Matches[1]; "Total" = [int]$Matches[2]; "Percentage" = [int]$Matches[3] }
32 | }
33 | else
34 | {
35 | Write-Warning ("No achievement progress found for {0}" -f $Game.Name)
36 | $Achieves += New-Object PSObject -Property @{"Name" = $Game.Name; "Completed" = 0; "Total" = 0; "Percentage" = 0 }
37 | }
38 | }
39 | }
40 |
41 | $Achieves | Sort-Object Name | Select Name, Completed, Total, Percentage
42 |
--------------------------------------------------------------------------------
/Misc/Move-PhotoDate.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Move photos into a date folder based on EXIF Date Taken field
4 |
5 | .DESCRIPTION
6 | Move photos to a folder in yyyy-MM-dd format, based on EXIF data.
7 |
8 | .NOTES
9 | File Name : Move-PhotoDate.ps1
10 | Author : John Sneddon
11 | Version : 1.0.0
12 | #>
13 |
14 | param([string]$file)
15 |
16 | function Get-TakenDate($file)
17 | {
18 | try
19 | {
20 | $image = New-Object System.Drawing.Bitmap -ArgumentList $file
21 | $date = $image.GetPropertyItem(36867).Value
22 | $takenValue = [System.Text.Encoding]::Default.GetString($date, 0, $date.Length - 1)
23 | $date = [DateTime]::ParseExact($takenValue, 'yyyy:MM:dd HH:mm:ss', $null)
24 | $image.Dispose()
25 | if ($date -eq $null) {
26 | Write-Host '{ No ''Date Taken'' in Exif }' -ForegroundColor Cyan
27 | return $null
28 | }
29 | return $date.ToString('yyyy-MM-dd')
30 | }
31 | catch
32 | {
33 | return $null
34 | }
35 | }
36 |
37 | [Reflection.Assembly]::LoadFile('C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Drawing.dll') | Out-Null
38 |
39 | gci *.jpg | foreach {
40 | Write-Host "$_`t->`t" -ForegroundColor Cyan -NoNewLine
41 |
42 | $Date = Get-TakenDate( $_.FullName)
43 |
44 | if ($Date)
45 | {
46 | $newDir = $_.DirectoryName +"\" + $date + "\"
47 |
48 | if (-not (Test-Path $newDir))
49 | {
50 | New-Item -ItemType Directory $NewDir | Out-Null
51 | }
52 | Write-Host ($newDir+$_.Name) -ForegroundColor Cyan
53 | mv $_.FullName ($newDir+$_.Name)
54 | }
55 | else
56 | {
57 | Write-Host "No Date Found" -ForegroundColor Yellow
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/VMware/Enable-HotAdd.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Enable memory and CPU hot-add for 2008 R2 servers
4 | .DESCRIPTION
5 | Basic script to bulk update VMs to enable CPU and memory Hot add. Only
6 | supports Server 2008 R2 at present, and VM will require a reboot for option
7 | to be available to use.
8 | .NOTES
9 | File Name : Enable-HotAdd.ps1
10 | Author : John Sneddon - @JohnSneddonAU
11 | Version : 1.0
12 |
13 | Version History
14 | ---------------
15 | 1.0.0 - Initial release
16 |
17 | .INPUTS
18 | vCenter Server must be specified
19 | .OUTPUTS
20 | HTML formatted email or HTML File
21 |
22 | .PARAMETER vCenter
23 | Specify the vCenter server(s) to connect to
24 |
25 | .EXAMPLE
26 | ./Enable-HotAdd -vCenter "vc.fqdn.domain.com"
27 | #>
28 | param
29 | (
30 | [ValidateScript({Test-Connection -Count 1 -Quiet -ComputerName $_})]
31 | $vCenter=Read-Host "Enter vCenter Server name"
32 | )
33 |
34 | function Enable-CPUMemHotAdd ($VMView)
35 | {
36 | $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
37 |
38 | $extra = New-Object VMware.Vim.optionvalue
39 | $extra.Key="vcpu.hotadd"
40 | $extra.Value="true"
41 | $vmConfigSpec.extraconfig += $extra
42 |
43 | $extra = New-Object VMware.Vim.optionvalue
44 | $extra.Key="mem.hotadd"
45 | $extra.Value="true"
46 | $vmConfigSpec.extraconfig += $extra
47 |
48 | $vmview.ReconfigVM($vmConfigSpec)
49 | }
50 | # Add Snapin
51 | if (!(Get-PSSnapin -name VMware.VimAutomation.Core -erroraction silentlycontinue)) {
52 | Add-PSSnapin VMware.VimAutomation.Core
53 | }
54 | Connect-VIServer $vCenter
55 |
56 | $VMs = Get-View -ViewType VirtualMachine | ?{$_.guest.guestFullName -eq "Microsoft Windows Server 2008 R2 (64-bit)"}
57 |
58 | $i = 0
59 | foreach ($VM in $VMs)
60 | {
61 | $perc = (100*$i++)/$VMs.Count
62 | Write-Progress -Activity ("Updating VM ({0} of {1})" -f $i, $VMs.Count) -Status ("{0:n2}% - {1}" -f $perc, $VM.Name) -PercentComplete $perc
63 | Enable-CPUMemHotAdd $VM
64 | }
65 | Write-Progress -Activity "Updating VM" -Status "Done" -Completed
66 |
--------------------------------------------------------------------------------
/Misc/Update-Readme.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Quick script to recreate README.md
4 |
5 | .DESCRIPTION
6 | Loop over child items and generate a new README.md content from script headers.
7 |
8 | .NOTES
9 | File Name : Update-Readme.ps1
10 | Author : John Sneddon
11 | Version : 1.0.0
12 | #>
13 |
14 | function Get-ScriptSynopsis
15 | {
16 | param ($File)
17 |
18 | try
19 | {
20 | $synopsis = (Select-String -path $File -pattern ".SYNOPSIS" -Context 1).Context.PostContext.trim()
21 | }
22 | catch
23 | {
24 | Write-Warning ("No Synopsis found for {0}" -f $File)
25 | $synopsis = ""
26 | }
27 |
28 | return $synopsis
29 | }
30 |
31 | $currDirectory = ""
32 |
33 | $content = "Personal Collection of Powershell scripts. No guarantees provided with any of these scripts.`n`n"
34 |
35 | foreach ($dir in (Get-ChildItem -Directory -Path ../ | Where-Object {$_.Name -notmatch "^_"} | Sort-Object Name))
36 | {
37 | $indent = ""
38 | $prevSubDir = ""
39 | $content += ("`n{0}`n=================`n" -f $dir.Name)
40 | foreach ($script in (Get-ChildItem -Path $dir.FullName -Recurse -Filter *.ps1 ))
41 | {
42 | $subDir = $script.DirectoryName.replace($dir.FullName, "").Trim("\")
43 |
44 | if ($subDir -ne "")
45 | {
46 | if ($SubDir -ne $prevSubDir)
47 | {
48 | if ($indent.length -ge 2)
49 | {
50 | $indent = $indent.Substring(2)
51 | }
52 | $content += ("{0}* {1}`n" -f $indent, $subDir)
53 | $indent += " "
54 | }
55 | else
56 | {
57 | #$indent = $indent.Substring(2)
58 | }
59 | $prevSubDir = $SubDir
60 |
61 | }
62 | else
63 | {
64 | $indent = ""
65 | }
66 | $currDirectory = $script.Directory.name
67 | $content += ("{0}* **{1}** - {2}`n" -f $indent, $script.name, (Get-ScriptSynopsis $Script.FullName))
68 | }
69 | }
70 | $content | Out-File ..\README.md
71 |
72 | # Changelog
73 | # =========
74 | # 1.0.0 - 2017-02-03 - Initial release
75 |
--------------------------------------------------------------------------------
/Server/DHCP/Sync-DHCPScope.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Triggered based on events from DHCP server to sync reservations.
4 |
5 | .DESCRIPTION
6 | Script is trigged based on events 106 and 107 in DHCP server event log to
7 | sync DHCP reservations in a particular scope to failover partner.
8 |
9 | .NOTES
10 | File Name : Invoke-DHCPSync.ps1
11 | Author : John Sneddon - @JohnSneddonAU
12 | Version : 1.0.0
13 |
14 | .LINK
15 | http://www.sneddo.net/2015/05/dhcp-fail-over/
16 |
17 | .INPUTS
18 | No inputs required
19 | .OUTPUTS
20 | None
21 |
22 | .PARAMETER eventRecordID
23 | Event ID of the triggering event
24 |
25 | .PARAMETER eventChannel
26 | Event Channel of the triggering event - will always be Microsoft-Windows-Dhcp-Server/Operational
27 | #>
28 | param($eventRecordID,$eventChannel)
29 |
30 | $regKey = "SYSTEM\CurrentControlSet\Services\DHCPServer\Parameters"
31 | $regKeyName = "SyncInProgress"
32 |
33 | # Get the exact event
34 | $event = Get-WinEvent -LogName $eventChannel -FilterXPath ""
35 |
36 | if (!(Get-Item Registry::HKEY_LOCAL_MACHINE\$regkey -ErrorAction SilentlyContinue).Value)
37 | {
38 | # Match the event Property to ScopeID - Format [[172.x.x.x]Scope name]
39 | if ($event.Properties[1].value -match "\[\[(.*)\].*\]")
40 | {
41 | $date = Get-date
42 | $scope = $Matches[1]
43 | $state = (Get-DhcpServerv4Scope $scope).State
44 |
45 | # Get scope and find the partner
46 | $partner = (Get-DhcpServerv4Failover -ScopeId $scope).PartnerServer
47 |
48 | # set reg key on partner
49 | $BaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$partner)
50 | $SubKey = $BaseKey.OpenSubKey($regKey,$true)
51 | $SubKey.SetValue($regKeyName , 1, [Microsoft.Win32.RegistryValueKind]::DWORD)
52 |
53 | # start replication
54 | Invoke-DhcpServerv4FailoverReplication –ScopeID $scope -Force
55 |
56 | # Remove reg key from partner
57 | $SubKey.SetValue($regKeyName , 0, [Microsoft.Win32.RegistryValueKind]::DWORD)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Server/Windows/Enable-CleanMgr.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Enables CleanMgr on the system
4 |
5 | .DESCRIPTION
6 | Copies the required files to use CleanMgr on a 2008 to 2012 server
7 |
8 | .NOTES
9 | File Name : Enable-CleanMgr.ps1
10 | Author : John Sneddon
11 | Version : 1.0
12 | #>
13 | $OS = (Get-WMIObject Win32_OperatingSystem).Caption -match "Microsoft Windows Server (20[0-9]{2} (R2)?) Enterprise|Standard"
14 | switch ($Matches[1])
15 | {
16 | "2012"
17 | {
18 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.2.9200.16384_none_c60dddc5e750072a\cleanmgr.exe" "$($env:SystemRoot)\System32"
19 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.2.9200.16384_en-us_b6a01752226afbb3\cleanmgr.exe.mui" "$($env:SystemRoot)\System32\en-US"
20 | }
21 | "2008 R2"
22 | {
23 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.1.7600.16385_none_c9392808773cd7da\cleanmgr.exe" "$($env:SystemRoot)\System32"
24 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.1.7600.16385_en-us_b9cb6194b257cc63\cleanmgr.exe.mui" "$($env:SystemRoot)\System32\en-US"
25 | }
26 | "2008"
27 | {
28 | switch ((Get-WMIObject Win32_OperatingSystem).OSArchitecture)
29 | {
30 | "64-bit"
31 | {
32 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr_31bf3856ad364e35_6.0.6001.18000_none_c962d1e515e94269\cleanmgr.exe" "$($env:SystemRoot)\System32"
33 | Copy-Item "$($env:SystemRoot)\winsxs\amd64_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.0.6001.18000_en-us_b9f50b71510436f2\cleanmgr.exe.mui" "$($env:SystemRoot)\System32\en-US"
34 | }
35 | "32-bit"
36 | {
37 | Copy-Item "$($env:SystemRoot)\winsxs\x86_microsoft-windows-cleanmgr_31bf3856ad364e35_6.0.6001.18000_none_6d4436615d8bd133\cleanmgr.exe" "$($env:SystemRoot)\System32"
38 | Copy-Item "$($env:SystemRoot)\winsxs\x86_microsoft-windows-cleanmgr.resources_31bf3856ad364e35_6.0.6001.18000_en-us_5dd66fed98a6c5bc\cleanmgr.exe.mui" "$($env:SystemRoot)\System32\en-US"
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ActiveDirectory/Get-NewADAccounts.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Script sends a HTML formatted email to user containing a list of AD
4 | account created in the period specified.
5 |
6 | .DESCRIPTION
7 | Sends an email to the specified email address with the parameters specified.
8 | Email contains a list of AD user accounts that were created in the specified
9 | period, containing the SamAccountName, account used to create the account,
10 | and when it was created.
11 |
12 | The "owner" permission is used to determine the creating account, however if
13 | the creator is a member of "Domain Admins" group, the name will not be
14 | displayed.
15 |
16 | .NOTES
17 | Author : John Sneddon
18 | Twitter : @JohnSneddonAU
19 | Web : http://www.sneddo.net
20 |
21 | .PARAMETER daysToReport
22 | Integer containing the number of days in reporting period. Defaults to 7.
23 |
24 | .PARAMETER mailServer
25 | Outgoing Mail (SMTP) server address. If not supplied, script will prompt
26 | for address.
27 |
28 | .PARAMETER mailFrom
29 | Address to use as the from address. If not supplied, script will prompt
30 | for address.
31 |
32 | .PARAMETER mailTo
33 | Email address of recipient. If not supplied, script will prompt
34 | for address.
35 |
36 | .PARAMETER mailSubject
37 | Subject line for the email. Defaults to "AD accounts created in past x days"
38 | Where x is the value of daysToReport parameter
39 |
40 | .EXAMPLE
41 | Send email to foo@bar.com using mail.bar.com as SMTP server,
42 | from foobar@bar.com containing accounts created in the past 7 days.
43 |
44 | AuditNewAccounts.ps1 -mailTo foo@bar.com -mailServer mail.bar.com -mailFrom foobar@bar.com
45 |
46 | .EXAMPLE
47 | Report on accounts created in past day
48 | AuditNewAccounts.ps1 -daysToReport 1 -mailTo foo@bar.com -mailServer mail.bar.com -mailFrom foobar@bar.com
49 | #>
50 | param (
51 | [int]$daysToReport=7,
52 | [string]$mailServer = (Read-Host "Enter mail server address"),
53 | [string]$mailFrom = (Read-Host "Send email from"),
54 | [string]$mailTo = (Read-Host "Send email to"),
55 | [string]$mailSubject = "AD accounts created in past $daysToReport days"
56 | )
57 |
58 | # Import AD Module
59 | Import-Module ActiveDirectory
60 |
61 | # Get date object for today minus $daysToReport
62 | $d = (Get-Date).AddDays(-$daysToReport)
63 |
64 | # Get AD users created since then and return owner,
65 | $users = Get-ADUser -filter {whenCreated -gt $d} -properties whenCreated, nTSecurityDescriptor |
66 | Select-Object SamAccountName, Name, @{"Name"="Creator"; "Expression"={$_.nTSecurityDescriptor.owner}}, whenCreated
67 |
68 | # Create a basic HTML table
69 | $mailContent = $users | ConvertTo-HTML -body "Users created since $d"
70 |
71 | # send email
72 | Send-MailMessage -From $mailFrom -To $mailTo -Subject $mailSubject -SmtpServer $mailServer -BodyAsHtml $mailContent
--------------------------------------------------------------------------------
/VMware/Export-VCSADatabase.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Backup and download the VCSA database
4 |
5 | .DESCRIPTION
6 | Uses WinSCP to connect to the VCSA, backup the database and then download to
7 | the local computer.
8 |
9 | .NOTES
10 | File Name : Export-VCSADatabase.ps1
11 | Author : John Sneddon
12 | Version : 1.0.0
13 |
14 | .REQUIREMENTS
15 | WinSCP
16 | #>
17 |
18 | $VCServers = @{$VCServers = @{"server" = @{"SshHostKeyFingerprint" = "ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"; "Username" = "root"; "Password" = "SECURESTRING"; }}
19 |
20 | $BackupLocation = "C:\temp\"
21 |
22 | "[{0}] Adding PowerCLI Snapin..." -f (Get-Date -Format "HH:mm:ss")
23 | Add-PSSnapIn VMware.VimAutomation.Core
24 |
25 | foreach ($VCServer in $VCServers.Keys.GetEnumerator())
26 | {
27 | "[{0}] Connecting to vCenter ({1})..." -f (Get-Date -Format "HH:mm:ss"), $VCServer
28 | Connect-VIServer $VCServer | Out-Null
29 |
30 |
31 | $Cred = (New-Object System.Management.Automation.PSCredential $VCServers[$VCServer].Username, ($VCServers[$VCServer].Password | ConvertTo-SecureString))
32 | $remoteFile = "/tmp/DBBackup-{0}-{1}.bak.gz" -f $VCServer, (Get-Date -f "yyyyMMdd")
33 |
34 | $cmd = "cd /opt/vmware/vpostgres/1.0/bin/; ./pg_dump VCDB -U vc -Fp -c | gzip > {0}" -f $remoteFile
35 |
36 | "[{0}] Starting backup..." -f (Get-Date -Format "HH:mm:ss")
37 | $r = Invoke-VMScript -VM (Get-VM $VCServer) -ScriptText $cmd -GuestCredential $cred
38 |
39 | if ($r.ExitCode -eq 0)
40 | {
41 | "[{0}] Backup successful" -f (Get-Date -Format "HH:mm:ss")
42 | try
43 | {
44 | # Load WinSCP .NET assembly
45 | Add-Type -Path "WinSCPnet.dll"
46 |
47 | # Setup session options
48 | $sessionOptions = New-Object WinSCP.SessionOptions
49 | $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
50 | $sessionOptions.HostName = $VCServer
51 | $sessionOptions.UserName = $VCServers[$VCServer].Username
52 | $sessionOptions.Password = $Cred.GetNetworkCredential().Password
53 | $sessionOptions.SshHostKeyFingerprint = $VCServers[$VCServer].SshHostKeyFingerprint
54 |
55 | $session = New-Object WinSCP.Session
56 |
57 | try
58 | {
59 | "[{0}] SFTP Connect" -f (Get-Date -Format "HH:mm:ss")
60 | # Connect
61 | $session.Open($sessionOptions)
62 |
63 | "[{0}] Begin transfer" -f (Get-Date -Format "HH:mm:ss")
64 | $transferResult = $session.GetFiles($remoteFile, $BackupLocation, $true)
65 |
66 | # Throw on any error
67 | $transferResult.Check()
68 |
69 | "[{0}] Transfer Complete" -f (Get-Date -Format "HH:mm:ss")
70 | }
71 | finally
72 | {
73 | # Disconnect, clean up
74 | $session.Dispose()
75 | }
76 | }
77 | catch [Exception]
78 | {
79 | "[{0}] {1}" -f (Get-Date -Format "HH:mm:ss"), $_.Exception.Message
80 | }
81 | }
82 | else
83 | {
84 | "[{0}] Backup FAILED" -f (Get-Date -Format "HH:mm:ss")
85 | }
86 |
87 | Disconnect-VIServer $VCServer | Out-Null
88 | }
89 |
--------------------------------------------------------------------------------
/VMware/Compare-VCRole.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Generate a HTML report comparing two vCenter roles
4 |
5 | .DESCRIPTION
6 | Generate a HTML report containing the differences between two vCenter roles.
7 |
8 | Items highlighted in green are present in that role, but not the other.
9 |
10 | .NOTES
11 | File Name : Compare-VCRole.ps1
12 | Author : John Sneddon
13 | Version : 1.0
14 |
15 | .PARAMETER ComputerName
16 | Specify the vCenter server name
17 | .PARAMETER Role1
18 | First Role
19 | .PARAMETER Role2
20 | Second Role
21 | #>
22 | Param
23 | (
24 | [ValidateScript({Test-Connection $_ -Quiet -Count 1})]
25 | [string]$ComputerName,
26 | [string]$Role1,
27 | [string]$Role2
28 | )
29 |
30 | $report = @"
31 |
32 |
33 |
44 |
45 |
46 |
47 | This report shows differences between two vCenter roles. Those highlighted in green are added to the role compared to the other role.
48 | | $($role1) | $($role2) |
49 | "@
50 | # Import Snapin
51 | if (!(Get-PSSnapin -name VMware.VimAutomation.Core -erroraction silentlycontinue)) {
52 | Add-PSSnapin VMware.VimAutomation.Core
53 | }
54 |
55 | # Connect to vCenter
56 | Connect-VIServer -Server $ComputerName | Out-Null
57 |
58 | # Get role privileges and differences
59 | $role1 = Get-VIRole $role1
60 | $role2 = Get-VIRole $role2
61 | $diff = Compare-Object $role1.PrivilegeList $role2.PrivilegeList
62 |
63 | $i = 0
64 | $c = $role1.PrivilegeList.count+$role1.PrivilegeList.count
65 | $report += ""
66 | foreach ($p in $role1.PrivilegeList)
67 | {
68 | Write-Progress -Activity "Compiling differences" -Status "Role1" -PercentComplete ($i*100/$c)
69 | $pObj = (Get-VIPrivilege -Id $p)
70 |
71 | switch (($diff | Where {$_.inputobject -eq $p}).sideIndicator)
72 | {
73 | "<=" { $class = " class='add'" }
74 | "=>" { $class = " class='delete'" }
75 | default { $class = "" }
76 | }
77 | $report += ("- {1}\{2}
" -f $class, $pObj.ParentGroup, $pObj.Name)
78 | $i++
79 | }
80 | $report += " | "
81 | foreach ($p in $role2.PrivilegeList)
82 | {
83 | Write-Progress -Activity "Compiling differences" -Status "Role2" -PercentComplete ($i*100/$c)
84 | $pObj = (Get-VIPrivilege -Id $p)
85 |
86 | switch (($diff | Where {$_.inputobject -eq $p}).sideIndicator)
87 | {
88 | "=>" { $class = " class='add'" }
89 | "<=" { $class = " class='delete'" }
90 | default { $class = "" }
91 | }
92 | $report += ("- {1}\{2}
" -f $class, ($pObj.ParentGroup), ($pObj.Name))
93 | }
94 | Write-Progress -Activity "Compiling differences" -Status "Complete" -Completed
95 | $report += " |
"
96 |
97 | $report | out-file "$($env:temp)\r.html"
98 | . "$($env:temp)\r.html"
99 |
--------------------------------------------------------------------------------
/Server/DHCP/Invoke-DHCPMigration.ps1:
--------------------------------------------------------------------------------
1 | # Requires -Modules DHCPServer -RunAsAdministrator
2 | Import-Module DHCPServer
3 |
4 | <#
5 | .SYNOPSIS
6 | Migrate a scope from the Source DHCP server to a new server
7 | .DESCRIPTION
8 |
9 | .NOTES
10 | File Name : Invoke-DHCPMigration.ps1
11 | Author : John Sneddon
12 | Version : 1.0.0
13 |
14 | .PARAMETER Source
15 | Source DHCP server.
16 | .PARAMETER Scope
17 | Scope to migrate
18 | .PARAMETER Destination
19 | Destination DHCP Server
20 | .PARAMETER BackupPath
21 | Path to backup DHCP server on import
22 | #>
23 | function Invoke-DHCPMigration
24 | {
25 | [CmdletBinding()]
26 | param
27 | (
28 | [Parameter(Mandatory=$true)]
29 | [string$Source,
30 |
31 | [Parameter(Mandatory=$true)]
32 | [string]$Scope,
33 |
34 | [Parameter(Mandatory=$true)]
35 | [string]$Destination,
36 |
37 | [string]$BackupPath="C:\DHCP\Backup",
38 |
39 | [switch]$DisableScope=$false
40 | )
41 | Begin
42 | {
43 | # Validate Source server is alive and is DHCP server
44 | if (-not (Test-Connection $Source -Quiet -Count 1))
45 | {
46 | Write-Error "Source server unavailable"
47 | }
48 | else
49 | {
50 | try
51 | {
52 | Get-DhcpServerv4Statistics -ComputerName $Source | Out-Null
53 | }
54 | catch
55 | {
56 | Write-Error "Cannot connect to Source DHCP server"
57 | }
58 | }
59 |
60 | # Validate Destination server is alive and is DHCP server
61 | if (-not (Test-Connection $Destination -Quiet -Count 1))
62 | {
63 | Write-Error "Destination server unavailable"
64 | }
65 | else
66 | {
67 | try
68 | {
69 | Get-DhcpServerv4Statistics -ComputerName $Destination | Out-Null
70 | }
71 | catch
72 | {
73 | Write-Error "Cannot connect to Destination DHCP server"
74 | }
75 | }
76 |
77 | # Validate Scope is valid
78 | <# Fix this later - use regex to determine ipv4/6
79 | try
80 | {
81 | Invoke-Expression "Get-DhcpServer$($version)scope -ComputerName $source -ScopeId $Scope"
82 | }
83 | catch
84 | {
85 | Write-Error "Could not get scope information from source server"
86 | }
87 | #>
88 | }
89 |
90 | Process
91 | {
92 | $File = ("{0}\{1}.xml" -f $Env:temp, $Scope)
93 |
94 | if ($DisableScope)
95 | {
96 | Write-Verbose "Disable Scope on Source server"
97 | Set-DhcpServerv4Scope -ScopeId $Scope -ComputerName $Source -State InActive
98 | }
99 | Write-Verbose "Exporting scope to file: $File"
100 | Export-DhcpServer -ComputerName $Source -ScopeId $Scope -Leases -File $File -Force
101 |
102 | Write-Verbose "Importing scope"
103 | Import-DhcpServer -ComputerName $Destination -File $File -BackupPath $BackupPath -Leases -ScopeOverwrite -Force
104 |
105 | if ($DisableScope)
106 | {
107 | Write-Verbose "Enable Scope on Destination server"
108 | Set-DhcpServerv4Scope -ScopeId $Scope -ComputerName $Destination -State Active
109 | }
110 | }
111 |
112 | End
113 | {
114 | Write-Verbose "Deleting migration file: $File"
115 | Remove-Item $File -Force
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/VMware/VMNoteSync.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Script syncs details from AD to vCenter notes.
4 | .DESCRIPTION
5 | Script performs the following general steps:
6 | 1. Find all VMs in all linked vCenter servers.
7 | 2. Query AD to find the Description and ManagedBy attibutes of the computer
8 | account.
9 | 3. The ManagedBy attribute is then resolved to individual users/groups
10 | 4. This information is then written back to vCenter
11 | .NOTES
12 | File Name : VMNoteSync.ps1
13 | Author : John Sneddon - @JohnSneddonAU
14 | Version : 1.1.6
15 | .PARAMETER VCServers
16 | Specify which vCenter server(s) to connect to
17 | .PARAMETER LogFile
18 | Specify the path to the logfile. Path to file must exist. Only used when
19 | DEBUG is set
20 | .PARAMETER DEBUG
21 | Enable Debug logging
22 | .PARAMETER Verbose
23 | Enable verbose output
24 | .EXAMPLE
25 | Normal operation
26 | ./VMNoteSync.ps1
27 | .EXAMPLE
28 |
29 |
30 | #>
31 | # 1.0.0 - Initial release
32 | # 1.1.0 - Only set notes if they differ
33 | # 1.1.1 - Bug fixes for groups not resolving correctly
34 | # 1.1.2 - Added step to update PowerCLI defaults to prevent script hanging
35 | # 1.1.3 - Write to logfile to aid debugging, move to parameters
36 | # 1.1.4 - Further work on Log file, bug fixes
37 | # 1.1.5 - Fix for server name not showing
38 | # 1.1.6 - Remove employer-specific code for release to web
39 |
40 | param
41 | (
42 | # [Parameter(Mandatory=$true)]
43 | [string[]]$VCServers = Read-Host "Enter vCenter Server Address",
44 |
45 | # Set log locations
46 | [ValidateScript({Split-Path $_ | Test-Path})]
47 | [string]$LogFile="C:\Program Files\KIT\VMware\debug.log",
48 |
49 | [switch]$DEBUG,
50 | [switch]$verbose,
51 |
52 | # Email details
53 | $mailServer = "smtp.yourdomain.com",
54 | $mailFrom = ("VMware Reports<{0}@yourdomain.com>" -f $env:computername),
55 | $mailSubject = "VM Notes updated",
56 | $mailTo = @("you@yourdomain.com"),
57 |
58 | [switch]$WhatIf
59 | )
60 |
61 | # Setup email style
62 | $emailContent = @"
63 |
64 |
65 |
74 |
75 |
76 | VM notes updated
77 | This list contains any VM notes that have been updated from AD information
78 | "@
79 |
80 | # AD cmdlets ignore ErrorAction parameter, ignore errors and handle errors by returned value
81 | $EAP = $ErrorActionPreference
82 | $ErrorActionPreference = "silentlyContinue"
83 |
84 | ################################################################################
85 | # FUNCTIONS #
86 | ################################################################################
87 | # Function to output to CLI and optionally file
88 | function Write-Log ($str, $showInCLI=$true)
89 | {
90 | $outStr = ("[{0}] {1}" -f (Get-Date -Format "HH:mm:ss"), $str)
91 | if ($showInCLI)
92 | {
93 | Write-Host $outStr
94 | }
95 |
96 | # if in debug mode, output to file
97 | if ($script:DEBUG)
98 | {
99 | ($script:debugLog).WriteLine($outStr)
100 | ($script:debugLog).flush()
101 | }
102 | }
103 |
104 | ###############################################################################
105 | # Setup #
106 | ###############################################################################
107 | # setup log file and write script start time to file
108 | if ($DEBUG)
109 | {
110 | $debugLog = [System.IO.StreamWriter] $LogFile
111 | Write-Log ("Script Started {0}" -f (Get-Date)) $false
112 | }
113 |
114 |
115 | ###############################################################################
116 | # Retrieve VMs #
117 | ###############################################################################
118 | # Add snapin and connect to VC
119 | Write-Log "Connecting to vCenter..."
120 | Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
121 | Connect-VIServer -Server $VCServers -AllLinked | Out-Null
122 |
123 | # Allow multiple connections
124 | Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -confirm:$false | Out-Null
125 |
126 | # get all Powered on VMs - ignore test PCs
127 | Write-Log "Fetching VMs..."
128 | $VMs = (Get-VM * | Where {$_.Powerstate -eq "PoweredOn" -and $_.Name -notmatch "^TPC.*" -and $_.Name -notmatch "PCWIN7DEV*"})
129 |
130 | # create a blank array and fill it with custom objects with all annotations
131 | Write-Log "Fetching VM Notes..."
132 | $VMList = @()
133 | foreach ($VM in $VMs)
134 | {
135 | if ($verbose)
136 | {
137 | Write-Log "`t $($VM.Name)"
138 | }
139 | $tmpObj = New-Object PSObject -Property @{"Name" = $VM.Name}
140 | ( $VM | Get-Annotation | foreach {$tmpObj | Add-Member NoteProperty $_.Name $_.Value})
141 | $VMList += $tmpObj
142 |
143 | Write-Progress -Activity "Fetching VM details..." -Status $VM.Name -PercentComplete (($VMList.count/$VMs.count)*100)
144 | }
145 | Write-Progress -Activity "Fetching VM details..." -Status "Complete" -Completed
146 |
147 | ###############################################################################
148 | # Find info from AD #
149 | ###############################################################################
150 | Write-Log "Finding Description/Manager information..."
151 | Import-Module ActiveDirectory
152 |
153 | $ManageGroups = @{} # Keep track of resolved groups to speed things up
154 | $ADList = @{} # Hash table to store Description/Manager for server
155 |
156 | # Find SME and System Owner
157 | for ($i=0; $i -lt $VMList.count; $i++)
158 | {
159 | try
160 | {
161 | $Computername = Get-ADComputer $VMList[$i].Name -Properties Description, ManagedBy
162 | }
163 | catch
164 | {
165 | $ComputerName = $null
166 | }
167 | $Manager = ""
168 |
169 | # Check if there is a manager listed
170 | if ($computerName.ManagedBy -ne $null)
171 | {
172 | if ($ManageGroups.Keys -notcontains $computerName.ManagedBy)
173 | {
174 | $addGroup = $true;
175 |
176 | try
177 | {
178 | $managers = Get-ADGroupMember $computerName.ManagedBy
179 |
180 | if ($managers -ne $null)
181 | {
182 | foreach ($manager in $managers)
183 | {
184 | $Manager += ";"+$manager.name
185 | }
186 | }
187 | }
188 | catch
189 | {
190 | # getting the group failed, the field must be a user - set as System Owner
191 | $addGroup = $false
192 | $Manager = ";"+(Get-ADUser $computername.ManagedBy).Name
193 | }
194 |
195 | # trim Manager strings to remove first semicolon
196 | # if no Manger, return a hyphen
197 | if ($Manager.length -gt 0)
198 | {
199 | $Manager = $Manager.SubString(1)
200 | }
201 | else
202 | {
203 | $Manager = "-"
204 | }
205 |
206 | # Add the details to a hashtable to avoid looking it up again
207 | if ($addGroup)
208 | {
209 | $ManageGroups.Add($computerName.ManagedBy,@{"Manager"=$Manager;"Description"=$computerName.Description})
210 | }
211 | }
212 | # We have seen this group before
213 | else
214 | {
215 | $Manager = $ManageGroups[$computerName.ManagedBy]["Manager"]
216 | $Description = $ManageGroups[$computerName.ManagedBy]["Description"]
217 | }
218 |
219 | # Create a new object and assign to $ADList
220 | $ADList.Add($computerName.Name, @{"Manager" = $Manager;
221 | "Description" = $computerName.Description})
222 | Write-Progress -Activity "Finding Description/Manager" -Status $Computername.Name -PercentComplete ((100*$i)/$VMList.count) -ErrorAction SilentlyContinue
223 | if ($verbose)
224 | {
225 | Write-Log (New-Object PSObject -Property @{ "Manager" = $Manager; "Description" = $computerName.Description } | Format-Table)
226 | }
227 | }
228 | }
229 | Write-Progress -Activity "Finding Description/Manager" -Status "Complete!" -Completed
230 |
231 | ###############################################################################
232 | # Set Notes on VMs #
233 | ###############################################################################
234 | Write-Log "Importing notes..."
235 | $updates = @()
236 | foreach ($VM in $VMList)
237 | {
238 | if ($ADList.Keys -contains $VM.Name)
239 | {
240 | # Get VM object reference
241 | $VMref = $VMs | Where {$_.Name -eq $VM.Name}
242 |
243 | if ($WhatIf)
244 | {
245 | if ($ADList[$VM.Name]["Description"] -ne $VM.Description)
246 | {
247 | $VMref | Set-Annotation -CustomAttribute "Description" -Value $ADList[$VM.Name]["Description"] -Whatif
248 | }
249 | if ($ADList[$VM.Name]["Manager"] -ne $VM."Manager")
250 | {
251 | $VMref | Set-Annotation -CustomAttribute "Manager" -Value $ADList[$VM.Name]["Manager"] -Whatif
252 | }
253 | }
254 | else
255 | {
256 | foreach ($field in @("Description", "Manager"))
257 | {
258 | if ($ADList[$VM.Name][$field] -ne $VM.$field)
259 | {
260 | ($VMref | Set-Annotation -CustomAttribute $field -Value $ADList[$VM.Name][$field])
261 | $updates += New-Object PSObject -Property @{"Server" = $VM.Name;
262 | "Field" = $field;
263 | "Value" = $ADList[$VM.Name][$field]}
264 | if ($verbose)
265 | {
266 | Write-Log "$($VM.Name) - $field updated $($ADList[$VM.Name][$field])"
267 | }
268 | }
269 | }
270 | }
271 | }
272 | else
273 | {
274 | if ($verbose)
275 | {
276 | Write-Log "$($VM.Name) - No update required"
277 | }
278 | }
279 | }
280 |
281 | # Close VC connection
282 | Disconnect-VIServer * -Confirm:$False
283 |
284 | ###############################################################################
285 | # Send email with updates made #
286 | ###############################################################################
287 | if ($updates.count -gt 0)
288 | {
289 | Write-Log "Sending Email..."
290 | $emailContent += "| Server | Field | Old Value | New Value |
"
291 | for ($i = 0; $i -lt $updates.count; $i++)
292 | {
293 | # Setup zebra table classes
294 | if ($i%2) { $class='alt' } else { $class='normal' }
295 |
296 | # Get Old value
297 | $OldValue = ($VMList | ?{$_.Name -eq $updates[$i].Server} | Select -ExpandProperty $updates[$i].Field)
298 | $updates[$i]
299 | $emailContent += ("| {1} | {2} | {3} | {4} |
" -f $class, $updates[$i].Server, $updates[$i].Field, $oldValue, $updates[$i].Value)
300 | }
301 | $emailContent += "
"
302 | Send-MailMessage -From $mailFrom -To $mailTo -Subject $mailSubject -SmtpServer $mailServer -BodyAsHtml $emailContent
303 | }
304 | else
305 | {
306 | Write-Log "No changes, no email generated"
307 | }
308 |
309 | # Close fileStream if used
310 | if ($DEBUG)
311 | {
312 | $debugLog.close()
313 | }
314 |
315 | # Reset EAP
316 | $ErrorActionPreference = $EAP
317 |
--------------------------------------------------------------------------------
/Profile/Microsoft.PowerShell_profile.ps1:
--------------------------------------------------------------------------------
1 | # Set Profile version - Used for update check
2 | $Version= 0.50
3 | # Profile location - should be network accessible share
4 | $ProfileLocation = "\\server\path\_profile\Microsoft.Powershell_profile.ps1"
5 |
6 | # Personal drive
7 | $PersonalDrive = "\\server\path\user"
8 |
9 | # Set History settings here - for persistent history accross sessions
10 | $HistoryLocation = "\\server\path\_profile\history.xml"
11 | $HistoryCount = 500 # Max: ([Int16]::MaxValue)
12 |
13 | # PSReadLine Location - directory containing module
14 | $PSReadLineLocation = "\\server\path\_profile\PSReadline"
15 |
16 | # Array of vCenter servers to prompt to join when PowerCLI snapin loaded
17 | $vCenterServers = @("server1", "server2", "server3")
18 |
19 |
20 | ################################################################################
21 | # FUNCTIONS #
22 | ################################################################################
23 | function Install-PowerCLIXmlSerializer {
24 | <#
25 | .SYNOPSIS
26 | Installs all the PowerCLI XmlSerializers.
27 |
28 | .DESCRIPTION
29 | Installs all the PowerCLI XmlSerializers.
30 | This is needed to speed-up the execution of the first PowerCLI cmdlet that is run in a PowerCLI session.
31 | After you install a new version of PowerCLI you only have to run this function once.
32 | If you use both the 32-bit and the 64-bit version of PowerCLI then you have to run this function in both versions.
33 | You must run this function with administrative privileges enabled.
34 |
35 | .EXAMPLE
36 | PS C:\> Install-PowerCLIXmlSerializers
37 |
38 | .INPUTS
39 | None
40 |
41 | .OUTPUTS
42 | System.String
43 |
44 | .NOTES
45 | Author: Robert van den Nieuwendijk
46 | Date: 18-2-2012
47 | Version: 1.0
48 |
49 | .LINK
50 | http://rvdnieuwendijk.com/2012/02/18/function-to-speed-up-the-execution-of-the-first-powercli-cmdlet/
51 | #>
52 |
53 | # Create an alias for ngen.exe
54 | Set-Alias ngen (Join-Path ([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()) ngen.exe)
55 |
56 | # Install all the PowerCLI XmlSerializers
57 | Get-ChildItem -Path $env:SystemRoot\assembly\GAC_MSIL\VimService*.XmlSerializers | `
58 | ForEach-Object {
59 | if ($_) {
60 | $Name = $_.Name
61 | Get-ChildItem -Path $_
62 | }
63 | } | `
64 | Select-Object -Property @{N="Name";E={$Name}},@{N="Version";E={$_.Name.Split("_")[0]}},@{N="PublicKeyToken";E={$_.Name.Split("_")[-1]}} | `
65 | ForEach-Object {
66 | if ($_) {
67 | ngen install "$($_.Name), Version=$($_.Version), Culture=neutral, PublicKeyToken=$($_.PublicKeyToken)"
68 | }
69 | }
70 | }
71 |
72 | function Get-Addons
73 | {
74 | <#
75 | .SYNOPSIS
76 | Returns a two-column list of Modules and snapins available on this machine
77 |
78 | .DESCRIPTION
79 | Prints a two-column list of all Available Modules and all registered snapins.
80 |
81 | .EXAMPLE
82 | PS C:\> Get-Addons
83 |
84 | .INPUTS
85 | None
86 |
87 | .OUTPUTS
88 | System.String
89 |
90 | .NOTES
91 | Author: John Sneddon
92 | Date: 13-10-2014
93 | Version: 1.0
94 | #>
95 | $m = Get-Module -ListAvailable | Select -expandproperty Name
96 | $s = Get-PSSnapin -Registered | Select -ExpandProperty Name
97 | $colwidth = (Get-Host).ui.RawUI.WindowSize.Width/2
98 |
99 | # Header
100 | Write-Host "".Padright((Get-Host).ui.RawUI.WindowSize.Width-1, "=")
101 | Write-Host ("| Available Modules{0}| Available Snapins{1}|" -f "".PadRight($colWidth-20), ("".PadRight($colWidth-20)))
102 | Write-Host "".Padright((Get-Host).ui.RawUI.WindowSize.Width-1, "=")
103 | for ($i = 0; $i -lt [System.Math]::Max($m.count, $s.count); $i++)
104 | {
105 | if ($m[$i])
106 | {
107 | Write-Host ("| {0}|" -f $m[$i].PadRight($colWidth-3)) -NoNewLine
108 | }
109 | else
110 | {
111 | Write-Host ("|{0}|" -f "".PadRight($colWidth-2)) -NoNewLine
112 | }
113 | if ($s[$i])
114 | {
115 | Write-Host (" {0}|" -f $s[$i].PadRight($colWidth-3) )
116 | }
117 | else
118 | {
119 | Write-Host ("{0}|" -f "".PadRight($colWidth-2))
120 | }
121 | }
122 | Write-Host "".Padright((Get-Host).ui.RawUI.WindowSize.Width-1, "-")
123 | Write-Host
124 | }
125 |
126 | function Add-PowerCLISnapin
127 | {
128 | if (!(Get-PSSnapin -name VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) {
129 | Write-Host ("Adding PowerCLI Core{0}[ ]" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-27)) -NoNewline
130 | try
131 | {
132 | Add-PSSnapin VMware.VimAutomation.Core
133 | Write-Host ("`rAdding PowerCLI Core{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-27)) -NoNewline
134 | Write-Host -ForegroundColor Green " OK " -NoNewLine
135 | $Host.UI.RawUI.WindowTitle += " [VM]"
136 | }
137 | catch
138 | {
139 | Write-Host("`rAdding PowerCLI Core{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-27)) -NoNewline
140 | Write-Host -ForegroundColor Red "FAIL" -NoNewLine
141 | }
142 | Write-Host "]"
143 | }
144 |
145 | Write-Host (Get-PowerCLIVersion).ToString()
146 |
147 | $vCenter = Get-Menu -Title "Connect to vCenter" -Question "Do you want to connect to a vCenter?" -Options $vCenterServers -AddNoOption
148 |
149 | if ($vCenter)
150 | {
151 | Connect-VIServer $vCenter -Credential (Get-Credential -UserName $env:username -Message "Enter vCentre Credentials") | Out-Null
152 | }
153 | }
154 | function Add-ExchangeSnapin
155 | {
156 | if (!(Get-PSSnapin -name Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue)) {
157 | if ((Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue -Registered).Count -gt 0)
158 | {
159 | Write-Host ("Adding Exchange Snapin{0}[ ]" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-29)) -NoNewline
160 | try
161 | {
162 | Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
163 | Write-Host ("`rAdding Exchange Snapin{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-29)) -NoNewline
164 | Write-Host -ForegroundColor Green " OK " -NoNewLine
165 | $Host.UI.RawUI.WindowTitle += " [Exchange]"
166 | }
167 | catch
168 | {
169 | Write-Host("`rAdding Exchange Snapin{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-29)) -NoNewline
170 | Write-Host -ForegroundColor Red "FAIL" -NoNewLine
171 | }
172 | Write-Host "]"
173 | }
174 | else
175 | {
176 | Write-Warning "Exchange Snapin not available on this host"
177 | }
178 | }
179 | }
180 |
181 | function Add-ADModule
182 | {
183 | if (!(Get-Module -name ActiveDirectoy -ErrorAction SilentlyContinue)) {
184 | Write-Host ("Adding Active Directory Module {0}[ ]" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-37)) -NoNewline
185 | try
186 | {
187 | Import-Module ActiveDirectory
188 | Write-Host ("`rAdding Active Directory Module{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-37)) -NoNewline
189 | Write-Host -ForegroundColor Green " OK " -NoNewLine
190 | $Host.UI.RawUI.WindowTitle += " [AD]"
191 | }
192 | catch
193 | {
194 | Write-Host("`rAdding Active Directory Module{0}[" -f "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-37)) -NoNewline
195 | Write-Host -ForegroundColor Red "FAIL" -NoNewLine
196 | }
197 | Write-Host "]"
198 | }
199 | }
200 |
201 | # Generate a Powershell console menu
202 | function Get-Menu
203 | {
204 | param ([String]$Title, [string]$Question, [string[]]$Options, [switch]$AddNoOption)
205 | $MenuOptions = @()
206 |
207 | if ($AddNoOption)
208 | {
209 | $MenuOptions += (New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No")
210 | }
211 |
212 | for ($i = 1; $i -le $Options.Count; $i++)
213 | {
214 | $MenuOptions += (New-Object System.Management.Automation.Host.ChoiceDescription "&$i $($Options[$i-1])", $Options[$i-1])
215 | }
216 |
217 | $result = $host.ui.PromptForChoice($title, $Question, $MenuOptions, 0)
218 |
219 | if ($AddNoOption)
220 | {
221 | $result = $result-1
222 | }
223 |
224 | if ($AddNoOption -and $result -eq 0)
225 | {
226 | return $null
227 | }
228 | return $Options[$result]
229 | }
230 |
231 | ################################################################################
232 | # ALIASES #
233 | ################################################################################
234 | Set-Alias vm Add-PowerCLISnapin
235 | Set-Alias ad Add-ADModule
236 | Set-Alias ex Add-ExchangeSnapin
237 |
238 | ################################################################################
239 | # INIT #
240 | ################################################################################
241 | # Check if profile exists or Profile is latest
242 | if ((!(Test-Path $Profile)) -or ($Version -lt (Get-Content $ProfileLocation | Select-String -Pattern "\$+Version\s*=").toString().split("=")[1].Trim()))
243 | {
244 | if (!(Test-Path $Profile))
245 | {
246 | New-Item -Type Directory (Split-Path $profile) | Out-Null
247 | }
248 | Copy-Item $ProfileLocation $Profile
249 | & $Profile
250 | break
251 | }
252 | # Check if PSReadLine is installed
253 | if (! (Get-Module PSReadLine))
254 | {
255 | # Copy the directory to the local profile location
256 | Copy-Item $PSReadLineLocation ("{0}\Modules\PSReadLine" -f (Split-Path $profile)) -Recurse -Force
257 | Import-Module PSReadLine
258 | }
259 | else
260 | {
261 | Import-Module PSReadLine
262 | }
263 |
264 | # Check if the H: drive is mapped
265 | if ($PersonalDrive -and -not (Test-Path "H:"))
266 | {
267 | New-PSDrive -Name "H" -PSProvider FileSystem -Root $PersonalDrive -Persist | Out-Null
268 | }
269 |
270 | Register-EngineEvent -SourceIdentifier powershell.exiting -SupportEvent -Action {
271 | Get-History -Count $HistoryCount | Export-Clixml $HistoryLocation
272 | }
273 |
274 | # Load History
275 | Import-CliXML $HistoryLocation | Add-History
276 |
277 | ################################################################################
278 | # STYLE #
279 | ################################################################################
280 | $Host.UI.RawUI.BackgroundColor = 'Black'
281 | $Host.UI.RawUI.ForegroundColor = 'White'
282 | $Host.PrivateData.ErrorForegroundColor = 'Red'
283 | $Host.PrivateData.ErrorBackgroundColor = 'Black'
284 | $Host.PrivateData.WarningForegroundColor = 'Yellow'
285 | $Host.PrivateData.WarningBackgroundColor = 'Black'
286 | $Host.PrivateData.DebugForegroundColor = 'Cyan'
287 | $Host.PrivateData.DebugBackgroundColor = 'Black'
288 | $Host.PrivateData.VerboseForegroundColor = 'DarkGray'
289 | $Host.PrivateData.VerboseBackgroundColor = 'Black'
290 | $Host.PrivateData.ProgressForegroundColor = 'White'
291 | $Host.PrivateData.ProgressBackgroundColor = 'DarkGray'
292 |
293 | # Set Console Size
294 | $pshost = Get-Host
295 | $pswindow = $pshost.ui.rawui
296 |
297 | $newsize = $pswindow.buffersize
298 | $newsize.height = 3000
299 | $newsize.width = 120
300 | $pswindow.buffersize = $newsize
301 |
302 | $newsize = $pswindow.windowsize
303 | $newsize.height = 50
304 | $newsize.width = 120
305 | $pswindow.windowsize = $newsize
306 |
307 | # Set Title
308 | if ($Host.UI.RawUI.WindowTitle -match "Administrator:")
309 | {
310 | $IsAdmin = $true
311 | $Admin = "*"
312 | }
313 |
314 | $Host.UI.RawUI.WindowTitle = ("PS{0} - User {1}{2} on {3}" -f $host.Version.ToString(), $env:username, $Admin, $env:ComputerName)
315 | Clear-Host
316 |
317 | ################################################################################
318 | # HEADER #
319 | ################################################################################
320 | Write-Host -ForegroundColor Green "".Padright((Get-Host).ui.RawUI.WindowSize.Width-1, "-")
321 | Write-Host -ForegroundColor Green " Profile Version: " -NoNewline
322 | Write-Host $Version
323 | Write-Host -ForegroundColor Green " User: ".PadRight(18) -NoNewLine
324 | if ($env:username -match "_a$")
325 | {
326 | Write-Host -ForegroundColor Red $env:username
327 | }
328 | else
329 | {
330 | Write-Host $env:username
331 | }
332 | Write-Host -ForegroundColor Green "".Padright((Get-Host).ui.RawUI.WindowSize.Width-1, "-")
333 | Write-Host
334 |
--------------------------------------------------------------------------------
/VMware/Set-PostDeployConfig.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Post deploy script to configure VMs
4 | .DESCRIPTION
5 | Configurations applied
6 | * AD Object move
7 | * Change CD Drive letter to Z:
8 | * Initialise Data disks (2012+ only at this stage)
9 | * SCOM Agent Install
10 | * Update Group Policy
11 | * Install Updates
12 |
13 | .NOTES
14 | Author : John Sneddon
15 | Version : 1.2.1
16 | #>
17 | ################################################################################
18 | # CONFIGURATION #
19 | ################################################################################
20 | # This is the only section that should require changes
21 |
22 | # $Config is a hashtable with the key as the environment (i.e. Prod or Test),
23 | # and values as a hastable of the following:
24 | # OU - [string] which OU should the AD object be moved to (DN)
25 | # WSUSDefault - [string] Change the group to this after patching (ServerAutoWeek2)
26 | # memberOf - [string[]] AD Groups to add the server to
27 | $Config = @{"Prod" = @{ "OU" = "";
28 | "WSUSDefault" = "ServerAutoWeek2";
29 | "memberOf" = @("",
30 | "") };
31 | "Test" = @{ "OU" = ""}
32 | }
33 |
34 |
35 | # Set Path of master script
36 | $Script = "\\Server\share\Set-PostDeployConfig.ps1"
37 | # Set Local Path
38 | $LocalScript = "C:\windows\temp\Set-PostDeployConfig.ps1"
39 | # Require user account to be in this domain
40 | $UserDomain = "SOUTHERNHEALTH"
41 |
42 | ################################################################################
43 | # FUNCTIONS #
44 | ################################################################################
45 | Function Get-ScriptVersion ($Path)
46 | {
47 | return [version](Get-Content $Path | Select-String -Pattern "Version\s*:").toString().split(":")[1].Trim()
48 | }
49 |
50 | Function Write-Status ($Message, $Status)
51 | {
52 | switch ($Status)
53 | {
54 | "OK" { Write-Host ("`r {0}{1}[" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline
55 | Write-Host -ForegroundColor Green " OK " -NoNewLine
56 | Write-Host "]"
57 | }
58 | "FAIL" { Write-Host ("`r {0}{1}[" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline
59 | Write-Host -ForegroundColor Red "FAIL" -NoNewLine
60 | Write-Host "]"
61 | }
62 | "N/A" { Write-Host ("`r {0}{1}[ N/A]" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8)))
63 | }
64 | default { Write-Host (" {0}{1}[ ]" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline }
65 | }
66 | }
67 |
68 | ################################################################################
69 | # INIT #
70 | ################################################################################
71 | # Requires a SOUTHERNHEALTH account
72 | if ($env:USERDOMAIN -ne $UserDomain)
73 | {
74 | Write-Warning "Not logged in as $UserDomain account. Please login as your admin account to complete configuration"
75 | $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null
76 | break
77 | }
78 |
79 | # Script must be run as administrator
80 | If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
81 | {
82 | $arguments = "& '" + $myinvocation.mycommand.definition + "'"
83 | Start-Process powershell -Verb runAs -ArgumentList $arguments
84 | Break
85 | }
86 |
87 | # Check if there is a newer version of the script
88 | if ((Get-ScriptVersion $LocalScript) -lt (Get-ScriptVersion $script))
89 | {
90 | Write-Warning "Newer version available!"
91 | Copy-Item $Script $LocalScript
92 | & $LocalScript
93 | break
94 | }
95 |
96 | ################################################################################
97 | # INFO GATHERING #
98 | ################################################################################
99 | ## Header #
100 | Write-Host "Monash Health Post-deployment configuration"
101 |
102 | ## Gather Information
103 | $Prod = New-Object System.Management.Automation.Host.ChoiceDescription "&Prod", "Production"
104 | $Test = New-Object System.Management.Automation.Host.ChoiceDescription "&Test", "Test"
105 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($Prod, $Test)
106 | $result = $host.ui.PromptForChoice("Choose environment", "Is the server Production or Test?", $options, 0)
107 | switch ($result)
108 | {
109 | 0 { $Environment = "Prod"; }
110 | 1 { $Environment = "Test"; }
111 | }
112 |
113 | # Get the Server description for BGInfo
114 | $ServerDesc = Read-Host "Server Description"
115 |
116 | Clear-Host
117 | Write-Host ""
118 | Write-Host ""
119 |
120 | ################################################################################
121 | # FUNCTION #
122 | ################################################################################
123 | ######## Active Directory ########
124 | # Move the AD Object
125 | Write-Status "Moving AD Object"
126 | Try
127 | {
128 | Import-Module ActiveDirectory
129 | Get-ADComputer $env:ComputerName | Move-ADObject -TargetPath $Config[$Environment].OU
130 | Write-Status "Moving AD Object" "OK"
131 | }
132 | catch
133 | {
134 | Write-Status "Moving AD Object" "FAIL"
135 | }
136 |
137 | ## Update Group Policy ##
138 | Write-Status "Updating Group Policy"
139 | $r = Start-Process -FilePath "C:\Windows\System32\gpupdate.exe" -ArgumentList "/Force" -NoNewWindow -Wait -RedirectStandardOutput null -PassThru
140 | if ($r.ExitCode -eq 0)
141 | {
142 | Write-Status "Updating Group Policy" "OK"
143 | }
144 | else
145 | {
146 | Write-Status "Updating Group Policy" "FAIL"
147 | }
148 |
149 | ######## Server Description ########
150 | Write-Status "Setting Server Description"
151 | $os = Get-WmiObject Win32_OperatingSystem
152 | $os.Description = $ServerDesc
153 | $os.Put() | Out-Null
154 | Write-Status "Setting Server Description" "OK"
155 |
156 | ######## Drives ########
157 | # Change drive letter of all CD drives, starting with Z: and work backwards
158 | Write-Status "Changing CD Drive letters"
159 | Try
160 | {
161 | $i = 0;
162 | Get-WmiObject Win32_cdromdrive | %{ $a = (mountvol $_.drive /l).Trim(); mountvol $_.drive /d; mountvol (([char](122-$i++)).ToString()+':') $a}
163 | # Wait for a bit - otherwise the drive letter not always available
164 | Start-Sleep -Seconds 5
165 | Write-Status "Changing CD Drive letters" "OK"
166 | }
167 | catch
168 | {
169 | Write-Status "Changing CD Drive letters" "FAIL"
170 | }
171 |
172 | # Use the Storage cmdlets if available
173 | Write-Host " Initialising Disks" -NoNewline
174 | if (@(Get-Command Get-Disk -ErrorAction SilentlyContinue).Count -gt 0)
175 | {
176 | # Initialize and format any extra disks
177 | $dataDisks = Get-Disk | Where partitionstyle -eq 'raw'
178 |
179 | if ($dataDisks -gt 1)
180 | {
181 | $i = 0
182 | foreach ($disk in $dataDisks)
183 | {
184 | Write-Status (" Initialising Disk {0}:" -f ([char](100+$i)))
185 | $disk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize | Format-Volume -FileSystem NTFS -Confirm:$false | Out-Null
186 |
187 | # Assign a drive letter - do this second otherwise we get an annoying prompt to format the disks
188 | $disk | Get-Partition | Where { $_.Type -eq "Basic" } | Set-Partition -NewDriveLetter ([char](100+$i))
189 | Write-Status (" Initialising Disk {0}:" -f ([char](100+$i))) "OK"
190 | $i++
191 | }
192 | }
193 | else
194 | {
195 | # No Data disks
196 | Write-Status "Initialising Disks" "N/A"
197 | }
198 | }
199 | else
200 | {
201 | Write-Warning "Storage cmdlets not available, you must be deploying an old OS"
202 | Write-Status "Initialising Disks" "N/A"
203 | }
204 |
205 | ########## Software ##########
206 | ## Install SCOM
207 | if ($Environment -eq "Prod")
208 | {
209 | Write-Status "Installing SCOM Agent"
210 | . $Env:WinDir\System32\msiexec.exe /i "\\Server\Share\SCOM-latest\MOMAgent.msi" /qn USE_SETTINGS_FROM_AD=0 USE_MANUALLY_SPECIFIED_SETTINGS=1 MANAGEMENT_GROUP=SOUTHERNHEALTH MANAGEMENT_SERVER_DNS=SHCLASCOAPP01 SECURE_PORT=5723 ACTIONS_USE_COMPUTER_ACCOUNT=1 AcceptEndUserLicenseAgreement=1
211 | Write-Status "Installing SCOM Agent" "OK"
212 | }
213 |
214 | ## Regenerate WSUS Client ID - 2008 seems to occasionally have trouble with WSUS otherwise
215 | if ((Get-WMIObject win32_OperatingSystem).Caption -match "Server 2008")
216 | {
217 | Write-Status "Fix 2008 WSUS Settings"
218 | Stop-Service wuauserv
219 | Remove-ItemProperty HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate SusClientID
220 | Remove-ItemProperty HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate AccountDomainSid
221 | Remove-ItemProperty HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate TargetGroup
222 | Remove-ItemProperty HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate TargetGroupEnabled
223 | Start-Service wuauserv
224 | Write-Status "Fix 2008 WSUS Settings" "OK"
225 | }
226 |
227 | ## Install Updates
228 | Write-Status "Searching for Windows Updates"
229 | # Search for relevant updates.
230 | $SearchResult = (New-Object -ComObject Microsoft.Update.Searcher).Search("IsInstalled=0 and Type='Software'").Updates
231 | Write-Status "Searching for Windows Updates" "OK"
232 |
233 |
234 | if ($SearchResult)
235 | {
236 | Write-Status ("Installing Windows Updates [{0}]" -f $SearchResult.Count)
237 |
238 | # Download updates.
239 | Write-Status "Downloading Updates"
240 | $Downloader = ( New-Object -ComObject Microsoft.Update.Session).CreateUpdateDownloader()
241 | $Downloader.Updates = $SearchResult
242 | $Downloader.Download() | Out-Null
243 | Write-Status " Downloading Updates" "OK"
244 |
245 | # Install updates.
246 | Write-Status " Installing Updates"
247 | $Installer = New-Object -ComObject Microsoft.Update.Installer
248 | $Installer.Updates = $SearchResult
249 | $Result = $Installer.Install() | Out-Null
250 | Write-Status ("Installing Windows Updates [{0}]" -f $SearchResult.Count) "OK"
251 | }
252 | else
253 | {
254 | Write-Status "Installing Windows Updates" "N/A"
255 | }
256 |
257 | ## Set Reg keys for Prod Servers
258 | # Set WSUS Group
259 | if ($Environment -eq "Prod")
260 | {
261 | Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name TargetGroup $Config[$Environment].WSUSDefault
262 | }
263 |
264 | ## Add to RDP Timeout group by default
265 | foreach ($grp in $Config[$Environment].memberOf)
266 | {
267 | Add-ADGroupMember -Identity $grp -Members ("{0}$" -f $Env:Computername)
268 | }
269 |
270 | Write-Host ""
271 | Write-Host "Remember to:"
272 | Write-Host " * Create Wiki page"
273 | Write-Host " * Approve SCOM Agent"
274 | Write-Host " * Add to Hobbit"
275 | Write-Host " * Add to Backups"
276 |
277 | ################################################################################
278 | # FINALISE #
279 | ################################################################################
280 | # Remove from Run regkey
281 | Remove-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run DeployScript
282 | # Delete Script
283 | Remove-Item $LocalScript
284 |
285 | # Reboot
286 | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Reboots the computer"
287 | $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Do not reboot"
288 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
289 | $result = $host.ui.PromptForChoice("Reboot Required", "Do you want to reboot now?", $options, 0)
290 |
291 | if ($result -eq 0)
292 | {
293 | Restart-Computer
294 | }
295 |
296 | <#
297 | CHANGELOG
298 | ---------
299 | 1.0.0 - Initial version
300 | Configurations applied
301 | * AD Object move
302 | * Change CD Drive letter to Z:
303 | * Initialise Data disks (2012+ only at this stage)
304 | * SCOM Agent Install
305 | * Update Group Policy
306 | * Install Updates
307 | 1.1.0 - Bugs fixed
308 | * Suppress additional output from WMI set
309 | Enhancements
310 | * Better feedback on Windows Update progress (no hang on search)
311 | 1.1.1 - Added Additional steps reminder
312 | 1.2.0 - Add memberOf config to add computer object to groups
313 | 1.2.1 - Add to ServerAutoWeek2 group
314 | #>
315 |
--------------------------------------------------------------------------------
/Exchange/Start-MailSearch.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Pretty GUI wrapper around mailbox search.
4 | .DESCRIPTION
5 | This script aims to make Exchange searches slightly less painful by wrapping
6 | the Search-Mailbox cmdlet in a pretty GUI.
7 | .NOTES
8 | File Name : Start-MailSearch
9 | Author : John Sneddon
10 | Version : 1.5.1
11 |
12 | CHANGELOG
13 | 1.0 - Initial script. Taken from Dave's script, and wrapped a nice UI around it
14 | 1.1 - Add a checkbox to actually do the deletecontent
15 | 1.2 - Added Search Criteria
16 | 1.3 - Add Option to run with delete if only searching. Hide the PS window.
17 | 1.4.0 - Add Sender search Criteria
18 | 1.5.0 - Add Date
19 | 1.5.1 - Add Date range options, slight refactor of code
20 |
21 | .INPUTS
22 | No inputs required
23 | .OUTPUTS
24 | No outputs
25 | #>
26 | Function Write-Status ($Message, $Status)
27 | {
28 | switch ($Status)
29 | {
30 | "OK" { Write-Host ("`r {0}{1}[" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline
31 | Write-Host -ForegroundColor Green " OK " -NoNewLine
32 | Write-Host "]"
33 | }
34 | "FAIL" { Write-Host ("`r {0}{1}[" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline
35 | Write-Host -ForegroundColor Red "FAIL" -NoNewLine
36 | Write-Host "]"
37 | }
38 | "N/A" { Write-Host ("`r {0}{1}[ N/A]" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8)))
39 | }
40 | default { Write-Host (" {0}{1}[ ]" -f $Message, "".PadRight((Get-Host).ui.RawUI.WindowSize.Width-($Message.Length+8))) -NoNewline }
41 | }
42 | }
43 |
44 | function Show-PSWindow
45 | {
46 | $Form.Hide()
47 | [UIWin32.Methods]::ShowWindow($Handle, 5) | Out-Null
48 | }
49 |
50 | function Show-SearchDialog
51 | {
52 | #[UIWin32.Methods]::ShowWindow($Handle, 0) | out-null
53 | $Form.ShowDialog() | out-null
54 | }
55 |
56 | function Invoke-MailboxSearch
57 | {
58 | Param (
59 | [string[]]$SearchIdentityList,
60 | [string]$SearchQuerySubject,
61 | [string]$SearchBody,
62 | [string]$SearchSender,
63 | [string]$SearchAttach,
64 | [string]$TargetMailbox,
65 | [string]$TargetMailboxFolder,
66 | $DateFrom,
67 | $DateTo,
68 | [Bool]$DeleteContent
69 | )
70 | Show-PSWindow
71 | Write-Host "Starting Search..."
72 |
73 | $SearchIdentityList = $SearchIdentityList -split "`r`n"
74 |
75 | # Search Query - Build from supplied text
76 | $SearchQueryString = ""
77 | if ($SearchQuerySubject)
78 | {
79 | $SearchQueryString += ('AND Subject:"{0}" ' -f $SearchQuerySubject)
80 | }
81 | if ($SearchBody)
82 | {
83 | $SearchQueryString += ('AND Body:"{0}" ' -f $SearchBody)
84 | }
85 | if ($SearchSender)
86 | {
87 | $SearchQueryString += ('AND From:"{0}" ' -f $SearchSender)
88 | }
89 | if ($SearchAttach)
90 | {
91 | $SearchQueryString += ('AND attachment={0} ' -f $SearchAttach)
92 | }
93 |
94 | # Do some basic validation on dates
95 | if ($DateFrom -gt $DateTo)
96 | {
97 | $DateFrom = (Get-Date ($DateTo)).AddDays(-1)
98 | }
99 | if ($DateTo -lt $DateFrom)
100 | {
101 | $DateTo = (Get-Date ($DateFrom)).AddDays(1)
102 | }
103 |
104 | if ($DateFrom -eq $DateTo)
105 | {
106 | $SearchQueryString += ('AND Received:{0}' -f ($DateFrom.ToString("yyyy-MM-dd")))
107 | }
108 | else
109 | {
110 | $SearchQueryString += ('AND Received:{0}..{1} ' -f ($DateFrom.ToString("yyyy-MM-dd"), $DateTo.ToString("yyyy-MM-dd")))
111 | }
112 |
113 | # Trim off the extra "AND"
114 | $SearchQueryString = $SearchQueryString.Trim("AND ")
115 |
116 | Write-Verbose "Searching: $SearchQueryString"
117 |
118 | Write-Host "Resolving unique mailboxes..."
119 | $SearchMailbox = @()
120 | $SearchIdentityList | Sort-Object -Unique | %{$SearchMailbox += Get-Mailbox $_ -ErrorAction SilentlyContinue }
121 |
122 | # Cycle through the identities to search. Check deletion is on/off and -force is on/off depending on whether you want to be
123 | # prompted for deletion. Deletion is -DeleteContent
124 | $i = 0;
125 | $totalRemoved = 0
126 | if ($SearchMailbox.count -gt 0)
127 | {
128 | foreach ($SearchIdentity in $SearchMailbox)
129 | {
130 | try
131 | {
132 | $PercentComplete = ($i*100/$SearchIdentityList.Count)
133 | Write-Progress -Activity "Searching Mailboxes" -Status ("{0}% - {1}" -f $PercentComplete, $SearchIdentity) -PercentComplete $PercentComplete
134 | if ($DeleteContent)
135 | {
136 | $result = Search-Mailbox -identity $SearchIdentity -SearchQuery $SearchQueryString -targetmailbox $TargetMailbox -targetfolder $TargetMailboxFolder -loglevel Full -deletecontent -force -WarningAction SilentlyContinue
137 | }
138 | else
139 | {
140 | $result = Search-Mailbox -identity $SearchIdentity -SearchQuery $SearchQueryString -targetmailbox $TargetMailbox -targetfolder $TargetMailboxFolder -loglevel Full -LogOnly -force -WarningAction SilentlyContinue
141 | }
142 | Write-Host ("{0}: {1} items found" -f $SearchIdentity.Name, $result.ResultItemsCount)
143 | $totalRemoved += $result.ResultItemsCount
144 | }
145 | catch
146 | {
147 | # Do nothing, just suppress the error
148 | Write-Error "Search Failed with query: $SearchQueryString"
149 | }
150 | $i++
151 | }
152 | }
153 | Write-Progress -Activity "Searching Mailboxes" -Status "Done" -Completed
154 |
155 | Write-Host "-------------------------------------"
156 | Write-Host ("{0} Email addresses in source list" -f $SearchIdentityList.count)
157 | Write-Host ("{0} Unique addresses" -f ($SearchIdentityList | Sort-Object -Unique).count)
158 | Write-Host ("{0} valid Mailboxes" -f $SearchMailbox.count)
159 | Write-Host ("{0} items found" -f $totalRemoved)
160 | Write-Host ""
161 | if (-not $DeleteContent)
162 | {
163 | Write-Host -ForegroundColor Yellow "********* Search only - Emails not deleted *********"
164 |
165 | $Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Yes"
166 | $No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No"
167 | $Update = New-Object System.Management.Automation.Host.ChoiceDescription "&Update", "Update Search"
168 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($Yes, $No, $Update)
169 | $result = $host.ui.PromptForChoice("Do you want to run the search again and delete content?", "Delete?", $options, 0)
170 | switch ($result)
171 | {
172 | 0 { # Run it again with delete
173 | Invoke-MailboxSearch $txtSearchMB.Text `
174 | $txtSearchString.Text `
175 | $txtSearchBody.Text `
176 | $txtSearchSender.Text `
177 | $txtSearchAttach.Text `
178 | $txtTgtMB.Text `
179 | $txtTgtFolder.Text `
180 | $dpDateFrom.SelectedDate `
181 | $dpDateTo.SelectedDate `
182 | $true
183 | }
184 | 1 { <# Do nothing #> }
185 | 2 { Show-SearchDialog }
186 | }
187 | }
188 | else
189 | {
190 | $Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Yes"
191 | $No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No"
192 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($No, $Yes)
193 | $result = $host.ui.PromptForChoice("Do you want to run another search?", "Run another?", $options, 0)
194 | switch ($result)
195 | {
196 | 0 { Exit }
197 | 1 { Show-SearchDialog }
198 | }
199 | }
200 | }
201 |
202 | ################################################################################
203 | # INITIALISATION #
204 | ################################################################################
205 | Clear-Host
206 | Write-Status "Loading Requirements..."
207 |
208 | # Add WPF Type
209 | Add-Type -AssemblyName PresentationFramework
210 |
211 | # Add the Exchange Snapin if not already loaded, so you don't have to open the exchange shell
212 | if (!(Get-PSSnapin -name Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue) -and
213 | (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue -Registered).Count -gt 0)
214 | {
215 | Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
216 | }
217 | Write-Status "Loading Requirements..." "OK"
218 |
219 | # Get the window handle to enable show/hide
220 | Add-Type -Name "Methods" -Namespace "UIWin32" -PassThru -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);' | Out-Null
221 | $Handle = (Get-Process -id $Pid).MainWindowHandle
222 |
223 |
224 | ################################################################################
225 | # GUI #
226 | ################################################################################
227 | # Use XAML to define the form, data to be populated in code
228 | [xml]$XAML_Main = @"
229 |
233 |
234 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 | to
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | Delete Email from Mailboxes
303 |
304 |
305 |
306 |
307 |
308 |
309 | "@
310 |
311 | #Read XAML
312 | $reader=(New-Object System.Xml.XmlNodeReader $XAML_Main)
313 | Try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
314 | Catch{Write-Error $l.XAMLError; Read-host; exit}
315 |
316 | # Read form controls into Powershell Objects for ease of modifcation
317 | $XAML_Main.SelectNodes("//*[@Name]") |
318 | foreach {Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
319 |
320 | ################################################################################
321 | # POPULATE FORM #
322 | ################################################################################
323 | $Form.Title += " - version " + (((Get-Content $MyInvocation.MyCommand.Path | select-string "Version : ([0-9.]+)") -split ":")[1])
324 |
325 | $txtTgtMB.Text = $env:Username -replace "_a", ""
326 | $txtTgtFolder.Text = ("Search Results - {0}" -f (get-date -Format "yyyyMMdd"))
327 |
328 | $dpDateFrom.SelectedDate = (Get-Date).AddDays(-1).ToString("yyyy-MM-dd" )
329 | $dpDateTo.SelectedDate = Get-Date -Format "yyyy-MM-dd"
330 |
331 | ################################################################################
332 | # EVENTS #
333 | ################################################################################
334 | # Add Search button handler
335 | $btnSearch.Add_Click({Invoke-MailboxSearch $txtSearchMB.Text `
336 | $txtSearchString.Text `
337 | $txtSearchBody.Text `
338 | $txtSearchSender.Text `
339 | $txtSearchAttach.Text `
340 | $txtTgtMB.Text `
341 | $txtTgtFolder.Text `
342 | $dpDateFrom.SelectedDate `
343 | $dpDateTo.SelectedDate `
344 | $chkDelete.IsChecked })
345 |
346 | ################################################################################
347 | # DISPLAY #
348 | ################################################################################
349 | Show-SearchDialog
350 |
--------------------------------------------------------------------------------
/Server/Dell/Set-DRACConfig.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | This script configures a DRAC to a standard config
4 | .DESCRIPTION
5 | This script will apply the appropriate config in the config folder, as well
6 | as generating a secure passwords and storing in Secret Server. It will also
7 | update firmware to the applicable firmware in the firmware folder.
8 |
9 | If a file is passed to the hostname field, it will loop over each value and
10 | apply the configuration.
11 |
12 | .NOTES
13 | File Name : Set-DRACConfig
14 | Author : John Sneddon - john.sneddon@monashhealth.org
15 | Version : 1.0.1
16 |
17 | CHANGELOG
18 | 1.0.0 - Initial script.
19 | 1.0.1 - Enable Auto Change for Secret Server
20 |
21 | There's probably a lot to clean up with this, but good enough for now...
22 |
23 | .INPUTS
24 | No inputs required
25 | .OUTPUTS
26 | No outputs
27 | #>
28 | ################################################################################
29 | # CONFIGURATION #
30 | ################################################################################
31 | # Path to racadm executable
32 | $racadmExe = "C:\Program Files\Dell\SysMgt\rac5\racadm.exe"
33 | # Secret Server win auth webservice URL
34 | $SecretServerURL = "https://secretserver/winauthwebservices/sswinauthwebservice.asmx"
35 | # SS template to use
36 | $SecretTemplate = "Dell DRAC Account"
37 | # SS folder to store passwords in
38 | $SecretServerFolder = "DRAC"
39 |
40 | ################################################################################
41 | # INITIALISATION #
42 | ################################################################################
43 | Clear-Host
44 | Write-Host "Loading Requirements..." -NoNewline
45 | # Add WPF Type
46 | Add-Type -AssemblyName PresentationFramework
47 | # Check if RacAdm is available
48 | if (-not (Test-Path $racadmExe))
49 | {
50 | Write-Error "RacAdmin not located in $racadmExe"
51 | exit
52 | }
53 | Write-Host "Done"
54 |
55 | # Hide the Powershell window
56 | Add-Type -Name "Methods" -Namespace "UIWin32" -PassThru -MemberDefinition '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);' | Out-Null
57 | $Handle = (Get-Process -id $Pid).MainWindowHandle
58 | [UIWin32.Methods]::ShowWindow($Handle, 0) | Out-Null
59 |
60 | ################################################################################
61 | # FUNCTIONS #
62 | ################################################################################
63 |
64 | function Invoke-DRACConfig
65 | {
66 | Param
67 | (
68 | [string]$DRAC,
69 | [string]$DRACUser,
70 | [string]$DRACPass,
71 | [Boolean]$Backup
72 | )
73 | $Form.Hide()
74 | [UIWin32.Methods]::ShowWindow($Handle, 5) | Out-Null
75 |
76 | # If we have a file path, retrieve the contents
77 | if (Test-Path $DRAC)
78 | {
79 | [string[]]$DRAC = Get-Content $DRAC
80 | }
81 |
82 | $i = 0;
83 | foreach ($dracInstance in $DRAC)
84 | {
85 | Write-Progress -Activity "Configuring DRAC" -Status $dracInstance -PercentComplete ($i*100/$DRAC.count)
86 | # RacAdm only uses IPs, so resolve the hostname to IP
87 | try
88 | {
89 | $DRACIP = [system.net.DNS]::Resolve($dracInstance).AddressList[0].IPAddressToString
90 | }
91 | catch
92 | {
93 | $DRACIP = ""
94 | Write-warning ("{0} cannot be resolved" -f $dracInstance)
95 | continue
96 | }
97 |
98 | if ($DRACIP)
99 | {
100 | # Try to determine DRAC verion
101 | Write-Debug "$racadmExe -r $DRACIP -u $DRACUser -p $DRACPass getconfig -g idracinfo -o idractype 2>&1"
102 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass getconfig -g idracinfo -o idractype 2>&1
103 |
104 | # Catch exception- e.g. Login failure
105 | if (($racOut | ?{ $_ -is [System.Management.Automation.ErrorRecord] }).count -gt 0)
106 | {
107 | $version = "???"
108 | $status = ($racOut | ?{ $_ -is [System.Management.Automation.ErrorRecord] })[0].exception
109 | }
110 | else
111 | {
112 | switch ([int]($racOut -match "^[0-9]+$")[0])
113 | {
114 | 6 { $version = "drac5" }
115 | 10 { $version = "drac6" }
116 | 16 { $version = "drac7" }
117 | 32 { $version = "drac8" }
118 | 33 { $version = "drac8" }
119 | default { $version = ""}
120 | }
121 |
122 | switch ($version)
123 | {
124 | "drac5" { $status = "DRAC5 is not supported" }
125 | "drac6" {
126 | if ($Backup)
127 | {
128 | Write-Host "Performing Backup"
129 | $tempFile = ("Backup/{0}-{1}.txt" -f (Get-Date -f "yyyyMMdd"), $dracInstance)
130 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass getconfig -f $tempFile;
131 | }
132 |
133 | # Get a random Password
134 | $password = Get-SecretServerPassword
135 | Write-Debug "New Password: $password"
136 |
137 | # Read the config and replace the root password
138 | $config = Get-Content "Config\drac6.txt"
139 | $config = $config -replace "{Password}", $password
140 |
141 | # Write to a temp file
142 | $tempFile = ("{0}{1}.txt" -f [System.IO.Path]::GetTempPath(), $dracInstance)
143 | $config | Out-File $tempFile -Encoding utf8
144 |
145 | Write-Debug "Importing Config"
146 | Write-Debug "$racadmExe -r $DRACIP -u $DRACUser -p $DRACPass config -f $tempFile 2>&1;"
147 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass config -f $tempFile 2>&1;
148 |
149 | $status = $racOut[-1]
150 |
151 | Remove-Item $tempFile
152 | if ($status -match "RAC configuration from file completed successfully")
153 | {
154 | # Update Secret Server
155 | Write-Debug "Updating Secret Server"
156 | Set-SecretServerPassword $dracInstance "root" $password ""
157 | }
158 |
159 | }
160 | "drac7" {
161 | if ($Backup)
162 | {
163 | Write-Host "Performing Backup"
164 | $tempFile = ("Backup/{0}-{1}.xml" -f (Get-Date -f "yyyyMMdd"), $dracInstance)
165 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass get -t xml -f $tempFile;
166 | }
167 |
168 | # Get a random Password
169 | $password = Get-SecretServerPassword
170 | Write-Debug "New Password: $password"
171 |
172 | # Read the config and replace the root password
173 | [xml]$config = Get-Content "Config\drac7.xml"
174 | ($config.SystemConfiguration.Component.Attribute | where {$_.Name -eq "Users.2#Password"})."#text" = $password
175 |
176 | # Write to a temp file
177 | $tempFile = ("{0}{1}.xml" -f [System.IO.Path]::GetTempPath(), $dracInstance)
178 | $config.Save($tempFile)
179 |
180 | Write-Debug "Importing Config"
181 | Write-Debug "$racadmExe -r $DRACIP -u $DRACUser -p $DRACPass set -t xml -f $tempFile;"
182 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass set -t xml -f $tempFile;
183 | # DRAC 7 creates a job to import the config, get the status of the job
184 | if ([string]$racOut -match "jobqueue view -i (JID_.*)""")
185 | {
186 | $jobID = $Matches[1]
187 | Write-Debug "Job found: $jobID"
188 |
189 | $jobComplete = $false
190 | while (-not $jobComplete)
191 | {
192 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass jobqueue view -i $jobID 2>&1
193 | # if the password has already changed, we'll get a login failure
194 | if ($racOut -match "ERROR: Login failed - invalid username or password")
195 | {
196 | $tmpPass = $DRACPass
197 | $DRACPass = $password
198 | }
199 | # Loop for a while until the job is complete
200 | if ([string]$racOut -match "Percent Complete=\[([^]]*)\]")
201 | {
202 | Write-Debug "Job complete: $($Matches[1])"
203 | if ($Matches[1] -eq "100")
204 | {
205 | $jobComplete = $true
206 | }
207 | else
208 | {
209 | Start-Sleep -Seconds 10
210 | }
211 | }
212 | if ([string]$racOut -match "Message=\[([^]]*)\]")
213 | {
214 | $status = $Matches[1]
215 | }
216 | }
217 | if ($tmpPass)
218 | {
219 | $DRACPass = $tmpPass
220 | }
221 | }
222 | else
223 | {
224 | write-Debug $racOut.ToString()
225 | }
226 | Remove-Item $tempFile
227 | if ($status -match "Successfully exported system configuration XML file." -or
228 | $status -match "Import of system configuration XML file operation completed with errors.")
229 | {
230 | # Update Secret Server
231 | Write-Debug "Updating Secret Server"
232 | Set-SecretServerPassword $dracInstance "root" $password ""
233 | }
234 | }
235 | "drac8" {
236 | if ($Backup)
237 | {
238 | Write-Host "Performing Backup"
239 | $tempFile = ("Backup/{0}-{1}.xml" -f (Get-Date -f "yyyyMMdd"), $dracInstance)
240 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass get -t xml -f $tempFile;
241 | }
242 |
243 | # Get a random Password
244 | $password = Get-SecretServerPassword
245 | Write-Debug "New Password: $password"
246 |
247 | # Read the config and replace the root password
248 | [xml]$config = Get-Content "Config\drac8.xml"
249 | ($config.SystemConfiguration.Component.Attribute | where {$_.Name -eq "Users.2#Password"})."#text" = $password
250 |
251 | # Write to a temp file
252 | $tempFile = ("{0}{1}.xml" -f [System.IO.Path]::GetTempPath(), $dracInstance)
253 | $config.Save($tempFile)
254 |
255 | Write-Debug "Importing Config"
256 | Write-Debug "$racadmExe -r $DRACIP -u $DRACUser -p $DRACPass set -t xml -f $tempFile;"
257 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass set -t xml -f $tempFile;
258 | # DRAC 7 creates a job to import the config, get the status of the job
259 | if ([string]$racOut -match "jobqueue view -i (JID_.*)""")
260 | {
261 | $jobID = $Matches[1]
262 | Write-Debug "Job found: $jobID"
263 |
264 | $jobComplete = $false
265 | while (-not $jobComplete)
266 | {
267 | $racOut = . "$racadmExe" -r $DRACIP -u $DRACUser -p $DRACPass jobqueue view -i $jobID 2>&1
268 | # if the password has already changed, we'll get a login failure
269 | if ($racOut -match "ERROR: Login failed - invalid username or password")
270 | {
271 | $tmpPass = $DRACPass
272 | $DRACPass = $password
273 | }
274 | # Loop for a while until the job is complete
275 | if ([string]$racOut -match "Percent Complete=\[([^]]*)\]")
276 | {
277 | Write-Debug "Job complete: $($Matches[1])"
278 | if ($Matches[1] -eq "100")
279 | {
280 | $jobComplete = $true
281 | }
282 | else
283 | {
284 | Start-Sleep -Seconds 10
285 | }
286 | }
287 | if ([string]$racOut -match "Message=\[([^]]*)\]")
288 | {
289 | $status = $Matches[1]
290 | }
291 | }
292 | if ($tmpPass)
293 | {
294 | $DRACPass = $tmpPass
295 | }
296 | }
297 | else
298 | {
299 | write-Debug $racOut.ToString()
300 | }
301 | Remove-Item $tempFile
302 | if ($status -match "Successfully exported system configuration XML file." -or
303 | $status -match "Import of system configuration XML file operation completed with errors.")
304 | {
305 | # Update Secret Server
306 | Write-Debug "Updating Secret Server"
307 | Set-SecretServerPassword $dracInstance "root" $password ""
308 | }
309 | }
310 | default {}
311 | }
312 | }
313 | Write-Host ("{0}[{1}] ({2}): {3}" -f $dracInstance, $DRACIP, $version, $status)
314 | }
315 | }
316 | Write-Progress -Activity "Configuring DRAC" -Status "Complete" -Completed
317 | }
318 |
319 | <#
320 | Generate a password using SecretServer
321 | #>
322 | function Get-SecretServerPassword
323 | {
324 | # Connect to web service
325 | $SecretServer = New-WebServiceProxy -uri $SecretServerURL -UseDefaultCredential
326 |
327 | # Generate a password
328 | $password = $SecretServer.GeneratePassword(1);
329 |
330 | if ($password.GeneratedPassword)
331 | {
332 | return $password.GeneratedPassword;
333 | }
334 | else
335 | {
336 | return $false
337 | }
338 | }
339 |
340 |
341 | function Set-SecretServerPassword
342 | {
343 | param
344 | (
345 | [string]$hostname,
346 | [string]$username,
347 | [string]$password,
348 | [string]$notes=""
349 | )
350 | # Connect to web service
351 | $SecretServer = New-WebServiceProxy -uri $SecretServerURL -UseDefaultCredential
352 |
353 | # Get the FolderId
354 | $SecretFolderId = $SecretServer.SearchFolders($SecretServerFolder).folders.id
355 |
356 | # see if the item exists already, if so update
357 | if ($SecretServer.SearchSecretsByFolder($hostname, $SecretFolderId, $false, $false, $false).SecretSummaries)
358 | {
359 | $Secret = $SecretServer.SearchSecretsByFolder($hostname, $SecretFolderId, $false, $false, $false).SecretSummaries[0]
360 | $Secret = $SecretServer.GetSecret($Secret.SecretId, $null, $null).Secret
361 | ($Secret.Items | where {$_.FieldName -eq "Password"}).value = $password
362 | $result = $SecretServer.UpdateSecret($Secret)
363 | }
364 | # Does not exist, add it
365 | else
366 | {
367 | # Get the list of fields
368 | $SecretTemplate = $SecretServer.GetSecretTemplates().SecretTemplates | where {$_.Name -match $SecretTemplate }
369 |
370 | $FieldIDs = $SecretTemplate.Fields | Select -ExpandProperty Id
371 |
372 | $FieldValues = @()
373 | foreach ($field in $SecretTemplate.Fields)
374 | {
375 | $FieldValues += (Get-Variable $field.DisplayName).value
376 | }
377 |
378 | $SecretServer.AddSecret($SecretTemplate.Id, $hostname, $FieldIDs, $FieldValues, $SecretFolderId)
379 |
380 | # Update secret to enable Auto Change
381 | $Secret = $SecretServer.SearchSecretsByFolder($hostname, $SecretFolderId, $false, $false, $false).SecretSummaries[0]
382 | $Secret = $SecretServer.GetSecret($Secret.SecretId, $true, $null).Secret
383 | $Secret.SecretSettings.AutoChangeEnabled = $true
384 | $Secret.SecretSettings.IsChangeToSettings = $true
385 | $result = $SecretServer.UpdateSecret($Secret)
386 | }
387 | }
388 |
389 | ################################################################################
390 | # GUI #
391 | ################################################################################
392 | # Use XAML to define the form, data to be populated in code
393 | [xml]$XAML_Main = @"
394 |
398 |
399 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 | root
436 | {USER}
437 |
438 |
439 |
440 |
441 |
442 | Update Firmware?
443 |
444 |
445 |
446 | Create Backup
447 |
448 |
449 |
450 |
451 |
452 | "@
453 |
454 | #Read XAML
455 | $reader=(New-Object System.Xml.XmlNodeReader $XAML_Main)
456 | Try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
457 | Catch{Write-Error $l.XAMLError; exit}
458 |
459 | # Read form controls into Powershell Objects for ease of modification
460 | $XAML_Main.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
461 |
462 | ################################################################################
463 | # POPULATE FORM #
464 | ################################################################################
465 | # Populate form inputs
466 | $txtDRACUser.items[1].Content = ("{0}\{1}" -f ($Env:UserDNSDomain).ToLower(), $Env:Username)
467 |
468 | # Configure a Browse Dialog
469 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
470 | $browseDialog = New-Object System.Windows.Forms.OpenFileDialog
471 | $browseDialog.DefaultExt = '.txt'
472 | $browseDialog.Filter = 'Text Files|*.txt|All Files|*.*'
473 | $browseDialog.FilterIndex = 0
474 | $browseDialog.InitialDirectory = $pwd
475 | $browseDialog.Multiselect = $false
476 | $browseDialog.RestoreDirectory = $true
477 | $browseDialog.Title = "Select text file containing DRACs"
478 | $browseDialog.ValidateNames = $true
479 |
480 | ################################################################################
481 | # EVENTS #
482 | ################################################################################
483 | # Add Browse button handler
484 | $btnBrowse.Add_Click({$browseDialog.ShowDialog(); $txtDRACAddress.Text = $browseDialog.FileName})
485 | # Add Config button handler
486 | $btnConfig.Add_Click({Invoke-DRACConfig $txtDRACAddress.Text $txtDRACUser.SelectedItem.Content $txtDRACPass.Password $chkBackup.IsChecked})
487 |
488 | ################################################################################
489 | # DISPLAY #
490 | ################################################################################
491 | $Form.ShowDialog() | out-null
492 |
--------------------------------------------------------------------------------
/_Tools/WmiExplorer.ps1:
--------------------------------------------------------------------------------
1 | #
2 | # WmiExplorer.ps1
3 | #
4 | # A GUI WMI explorer and WMI Method Help generator
5 | #
6 | # /\/\o\/\/ 2006
7 | # www.ThePowerShellGuy.com
8 | #
9 |
10 | # load Forms NameSpace
11 |
12 | [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
13 | [void][reflection.assembly]::LoadWithPartialName("System.Drawing")
14 |
15 | #region BuildTheForm build in C# then translated to powershell
16 |
17 | #region Make the form
18 |
19 | $frmMain = new-object Windows.Forms.form
20 | $frmMain.Size = new-object System.Drawing.Size @(800,600)
21 | $frmMain.text = "/\/\o\/\/'s PowerShell WMI Explorer"
22 |
23 | #endregion Make the form
24 |
25 | #region Define Used Controls
26 |
27 | $MainMenu = new-object System.Windows.Forms.MenuStrip
28 | $statusStrip = new-object System.Windows.Forms.StatusStrip
29 | $FileMenu = new-object System.Windows.Forms.ToolStripMenuItem
30 | $ToolMenu = new-object System.Windows.Forms.ToolStripMenuItem('&tools')
31 |
32 | $miQuery = new-object System.Windows.Forms.ToolStripMenuItem('&Query (run)')
33 |
34 | $miSelectQuery = new-object System.Windows.Forms.ToolStripMenuItem('&SelectQuery')
35 | $miSelectQuery.add_Click({$sq | out-propertyGrid;$wmiSearcher.Query = $sq})
36 | [void]$ToolMenu.DropDownItems.Add($miSelectQuery)
37 |
38 | $miRelatedObjectQuery = new-object System.Windows.Forms.ToolStripMenuItem('&RelatedObjectQuery')
39 | $miRelatedObjectQuery.add_Click({$roq | out-propertyGrid;$wmiSearcher.Query = $roq})
40 | [void]$ToolMenu.DropDownItems.Add($miRelatedObjectQuery)
41 |
42 | $miRelationshipQuery = new-object System.Windows.Forms.ToolStripMenuItem('&RelationshipQuery')
43 | $miRelationshipQuery.add_Click({$rq | out-propertyGrid ;$wmiSearcher.Query = $rq})
44 | [void]$ToolMenu.DropDownItems.Add($miRelationshipQuery)
45 |
46 | $oq = new-object System.Management.ObjectQuery
47 | $eq = new-object System.Management.EventQuery
48 | $sq = new-object System.Management.SelectQuery
49 | $roq = new-object System.Management.RelatedObjectQuery
50 | $rq = new-object System.Management.RelationshipQuery
51 | $wmiSearcher = [wmisearcher]''
52 | [void]$ToolMenu.DropDownItems.Add($miQuery)
53 |
54 | $miQuery.add_Click({
55 |
56 | $wmiSearcher | out-propertyGrid
57 | $moc = $wmiSearcher.get()
58 | $DT = new-object System.Data.DataTable
59 | $DT.TableName = $lblClass.text
60 | $Col = new-object System.Data.DataColumn
61 | $Col.ColumnName = "WmiPath"
62 | $DT.Columns.Add($Col)
63 |
64 | $i = 0
65 | $j = 0 ;$lblInstances.Text = $j; $lblInstances.Update()
66 |
67 | $MOC |
68 | ForEach-Object {
69 | $j++ ;$lblInstances.Text = $j; $lblInstances.Update()
70 | $MO = $_
71 |
72 | # Make a DataRow
73 |
74 | $DR = $DT.NewRow()
75 | $Col = new-object System.Data.DataColumn
76 | $DR.Item("WmiPath") = $mo.__PATH
77 |
78 | $MO.psbase.properties |
79 | ForEach-Object {
80 |
81 | $prop = $_
82 |
83 | If ($i -eq 0) {
84 |
85 | # Only On First Row make The Headers
86 |
87 | $Col = new-object System.Data.DataColumn
88 | $Col.ColumnName = $prop.Name.ToString()
89 |
90 | $prop.psbase.Qualifiers |
91 | ForEach-Object {
92 | If ($_.Name.ToLower() -eq "key") {
93 | $Col.ColumnName = $Col.ColumnName + "*"
94 | }
95 | }
96 | $DT.Columns.Add($Col)
97 | }
98 |
99 | # fill dataRow
100 |
101 | if ($prop.value -eq $null) {
102 | $DR.Item($prop.Name) = "[empty]"
103 | } ElseIf ($prop.IsArray) {
104 | $DR.Item($prop.Name) =[string]::Join($prop.value ,";")
105 | } Else {
106 | $DR.Item($prop.Name) = $prop.value
107 | #Item is Key try again with *
108 | trap{$DR.Item("$($prop.Name)*") = $prop.Value.tostring();continue}
109 | }
110 |
111 | } #end ForEach
112 |
113 | # Add the row to the DataTable
114 |
115 | $DT.Rows.Add($DR)
116 | $i += 1
117 |
118 | }
119 |
120 | $DGInstances.DataSource = $DT.psObject.baseobject
121 | $status.Text = "Retrieved $j Instances"
122 | $status.BackColor = 'YellowGreen'
123 | $statusstrip.Update()
124 |
125 | })#$miQuery.add_Click
126 |
127 |
128 | $miQuit = new-object System.Windows.Forms.ToolStripMenuItem('&quit')
129 |
130 | $miQuit.add_Click({$frmMain.close()})
131 |
132 | $SplitContainer1 = new-object System.Windows.Forms.SplitContainer
133 | $splitContainer2 = new-object System.Windows.Forms.SplitContainer
134 | $splitContainer3 = new-object System.Windows.Forms.SplitContainer
135 |
136 | $grpComputer = new-object System.Windows.Forms.GroupBox
137 | $grpNameSpaces = new-object System.Windows.Forms.GroupBox
138 | $grpClasses = new-object System.Windows.Forms.GroupBox
139 | $grpClass = new-object System.Windows.Forms.GroupBox
140 | $grpInstances = new-object System.Windows.Forms.GroupBox
141 | $grpStatus = new-object System.Windows.Forms.GroupBox
142 |
143 | $txtComputer = new-object System.Windows.Forms.TextBox
144 | $btnConnect = new-object System.Windows.Forms.Button
145 | $btnInstances = new-object System.Windows.Forms.Button
146 |
147 | $tvNameSpaces = new-object System.Windows.Forms.TreeView
148 | $lvClasses = new-object System.Windows.Forms.ListView
149 |
150 | $clbProperties = new-object System.Windows.Forms.CheckedListBox
151 | $clbProperties.CheckOnClick = $true
152 | $lbMethods = new-object System.Windows.Forms.ListBox
153 |
154 | $label1 = new-object System.Windows.Forms.Label
155 | $label2 = new-object System.Windows.Forms.Label
156 | $lblServer = new-object System.Windows.Forms.Label
157 | $lblPath = new-object System.Windows.Forms.Label
158 | $lblNameSpace = new-object System.Windows.Forms.Label
159 | $label6 = new-object System.Windows.Forms.Label
160 | $lblClass = new-object System.Windows.Forms.Label
161 | $label10 = new-object System.Windows.Forms.Label
162 | $lblClasses = new-object System.Windows.Forms.Label
163 | $label12 = new-object System.Windows.Forms.Label
164 | $lblProperties = new-object System.Windows.Forms.Label
165 | $label8 = new-object System.Windows.Forms.Label
166 | $lblMethods = new-object System.Windows.Forms.Label
167 | $label14 = new-object System.Windows.Forms.Label
168 | $lblInstances = new-object System.Windows.Forms.Label
169 | $label16 = new-object System.Windows.Forms.Label
170 |
171 | $dgInstances = new-object System.Windows.Forms.DataGridView
172 | $TabControl = new-object System.Windows.Forms.TabControl
173 | $tabPage1 = new-object System.Windows.Forms.TabPage
174 | $tabInstances = new-object System.Windows.Forms.TabPage
175 | $rtbHelp = new-object System.Windows.Forms.RichTextBox
176 | $tabMethods = new-object System.Windows.Forms.TabPage
177 | $rtbMethods = new-object System.Windows.Forms.RichTextBox
178 | #endregion Define Used Controls
179 |
180 | #region Suspend the Layout
181 |
182 | $splitContainer1.Panel1.SuspendLayout()
183 | $splitContainer1.Panel2.SuspendLayout()
184 | $splitContainer1.SuspendLayout()
185 | $splitContainer2.Panel1.SuspendLayout()
186 | $splitContainer2.Panel2.SuspendLayout()
187 | $splitContainer2.SuspendLayout()
188 | $grpComputer.SuspendLayout()
189 | $grpNameSpaces.SuspendLayout()
190 | $grpClasses.SuspendLayout()
191 | $splitContainer3.Panel1.SuspendLayout()
192 | $splitContainer3.Panel2.SuspendLayout()
193 | $splitContainer3.SuspendLayout()
194 | $grpClass.SuspendLayout()
195 | $grpStatus.SuspendLayout()
196 | $grpInstances.SuspendLayout()
197 | $TabControl.SuspendLayout()
198 | $tabPage1.SuspendLayout()
199 | $tabInstances.SuspendLayout()
200 | $FrmMain.SuspendLayout()
201 |
202 | #endregion Suspend the Layout
203 |
204 | #region Configure Controls
205 |
206 | [void]$MainMenu.Items.Add($FileMenu)
207 | [void]$MainMenu.Items.Add($ToolMenu)
208 | $MainMenu.Location = new-object System.Drawing.Point(0, 0)
209 | $MainMenu.Name = "MainMenu"
210 | $MainMenu.Size = new-object System.Drawing.Size(1151, 24)
211 | $MainMenu.TabIndex = 0
212 | $MainMenu.Text = "Main Menu"
213 |
214 | #
215 | # statusStrip1
216 | #
217 | $statusStrip.Location = new-object System.Drawing.Point(0, 569)
218 | $statusStrip.Name = "statusStrip"
219 | $statusStrip.Size = new-object System.Drawing.Size(1151, 22);
220 | $statusStrip.TabIndex = 1
221 | $statusStrip.Text = "statusStrip"
222 |
223 | $splitContainer1.Dock = [System.Windows.Forms.DockStyle]::Fill
224 | $splitContainer1.Location = new-object System.Drawing.Point(0, 24)
225 | $splitContainer1.Name = "splitContainer1"
226 | $splitContainer1.Panel1.Controls.Add($splitContainer2)
227 |
228 | $splitContainer1.Panel2.Controls.Add($splitContainer3)
229 | $splitContainer1.Size = new-object System.Drawing.Size(1151, 545)
230 | $splitContainer1.SplitterDistance = 372
231 | $splitContainer1.TabIndex = 2
232 |
233 | $splitContainer2.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
234 | $splitContainer2.Dock = [System.Windows.Forms.DockStyle]::Fill
235 | $splitContainer2.Location = new-object System.Drawing.Point(0, 0)
236 | $splitContainer2.Name = "splitContainer2"
237 | $splitContainer2.Orientation = [System.Windows.Forms.Orientation]::Horizontal
238 |
239 | $splitContainer2.Panel1.BackColor = [System.Drawing.SystemColors]::Control
240 | $splitContainer2.Panel1.Controls.Add($grpNameSpaces)
241 | $splitContainer2.Panel1.Controls.Add($btnConnect)
242 | $splitContainer2.Panel1.Controls.Add($grpComputer)
243 |
244 | $splitContainer2.Panel2.Controls.Add($grpClasses)
245 | $splitContainer2.Size = new-object System.Drawing.Size(372, 545)
246 | $splitContainer2.SplitterDistance = 302
247 | $splitContainer2.TabIndex = 0
248 |
249 | #
250 | # fileMenu
251 | #
252 | [void]$fileMenu.DropDownItems.Add($miQuit)
253 | $fileMenu.Name = "fileMenu"
254 | $fileMenu.Size = new-object System.Drawing.Size(35, 20)
255 | $fileMenu.Text = "&File"
256 |
257 | $grpComputer.Anchor = "top, left, right"
258 | $grpComputer.Controls.Add($txtComputer)
259 | $grpComputer.Location = new-object System.Drawing.Point(12, 3)
260 | $grpComputer.Name = "grpComputer"
261 | $grpComputer.Size = new-object System.Drawing.Size(340, 57)
262 | $grpComputer.TabIndex = 0
263 | $grpComputer.TabStop = $false
264 | $grpComputer.Text = "Computer"
265 |
266 | $txtComputer.Anchor = "top, left, right"
267 | $txtComputer.Location = new-object System.Drawing.Point(7, 20)
268 | $txtComputer.Name = "txtComputer"
269 | $txtComputer.Size = new-object System.Drawing.Size(244, 20)
270 | $txtComputer.TabIndex = 0
271 | $txtComputer.Text = "."
272 |
273 |
274 | $btnConnect.Anchor = "top, right"
275 | $btnConnect.Location = new-object System.Drawing.Point(269, 23);
276 | $btnConnect.Name = "btnConnect"
277 | $btnConnect.Size = new-object System.Drawing.Size(75, 23)
278 | $btnConnect.TabIndex = 1
279 | $btnConnect.Text = "Connect"
280 | $btnConnect.UseVisualStyleBackColor = $true
281 |
282 | #
283 | # grpNameSpaces
284 | #
285 | $grpNameSpaces.Anchor = "Bottom, top, left, right"
286 | $grpNameSpaces.Controls.Add($tvNameSpaces)
287 | $grpNameSpaces.Location = new-object System.Drawing.Point(12, 67)
288 | $grpNameSpaces.Name = "grpNameSpaces"
289 | $grpNameSpaces.Size = new-object System.Drawing.Size(340, 217)
290 | $grpNameSpaces.TabIndex = 2
291 | $grpNameSpaces.TabStop = $false
292 | $grpNameSpaces.Text = "NameSpaces"
293 | #
294 | # grpClasses
295 | #
296 | $grpClasses.Anchor = "Bottom, top, left, right"
297 |
298 | $grpClasses.Controls.Add($lvClasses)
299 | $grpClasses.Location = new-object System.Drawing.Point(12, 14)
300 | $grpClasses.Name = "grpClasses"
301 | $grpClasses.Size = new-object System.Drawing.Size(340, 206)
302 | $grpClasses.TabIndex = 0
303 | $grpClasses.TabStop = $False
304 | $grpClasses.Text = "Classes"
305 | #
306 | # tvNameSpaces
307 | #
308 | $tvNameSpaces.Anchor = "Bottom, top, left, right"
309 |
310 | $tvNameSpaces.Location = new-object System.Drawing.Point(7, 19)
311 | $tvNameSpaces.Name = "tvNameSpaces"
312 | $tvNameSpaces.Size = new-object System.Drawing.Size(325, 184)
313 | $tvNameSpaces.TabIndex = 0
314 | #
315 | # tvClasses
316 | #
317 | $lvClasses.Anchor = "Bottom, top, left, right"
318 |
319 | $lvClasses.Location = new-object System.Drawing.Point(7, 19)
320 | $lvClasses.Name = "tvClasses"
321 | $lvClasses.Size = new-object System.Drawing.Size(325, 172)
322 | $lvClasses.TabIndex = 0
323 | $lvClasses.UseCompatibleStateImageBehavior = $False
324 | $lvClasses.ShowItemToolTips = $true
325 | $lvClasses.View = 'Details'
326 | $colName = $lvClasses.Columns.add('Name')
327 | $colname.Width = 160
328 | $colPath = $lvClasses.Columns.add('Description')
329 | $colname.Width = 260
330 | $colPath = $lvClasses.Columns.add('Path')
331 | $colname.Width = 260
332 | #
333 | # splitContainer3
334 | #
335 | $splitContainer3.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
336 | $splitContainer3.Dock = [System.Windows.Forms.DockStyle]::Fill
337 | $splitContainer3.Location = new-object System.Drawing.Point(0, 0)
338 | $splitContainer3.Name = "splitContainer3"
339 | $splitContainer3.Orientation = [System.Windows.Forms.Orientation]::Horizontal
340 | #
341 | # splitContainer3.Panel1
342 | #
343 | $splitContainer3.Panel1.Controls.Add($grpStatus)
344 | $splitContainer3.Panel1.Controls.Add($grpClass)
345 | #
346 | # splitContainer3.Panel2
347 | #
348 | $splitContainer3.Panel2.Controls.Add($TabControl)
349 | $splitContainer3.Size = new-object System.Drawing.Size(775, 545)
350 | $splitContainer3.SplitterDistance = 303
351 | $splitContainer3.TabIndex = 0
352 | #
353 | # grpClass
354 | #
355 | $grpClass.Anchor = "Bottom, top, left, right"
356 | $grpClass.Controls.Add($lblInstances)
357 | $grpClass.Controls.Add($label16)
358 | $grpClass.Controls.Add($lblMethods)
359 | $grpClass.Controls.Add($label14)
360 | $grpClass.Controls.Add($lblProperties)
361 | $grpClass.Controls.Add($label8)
362 | $grpClass.Controls.Add($lblClass)
363 | $grpClass.Controls.Add($label10)
364 | $grpClass.Controls.Add($lbMethods)
365 | $grpClass.Controls.Add($clbProperties)
366 | $grpClass.Controls.Add($btnInstances)
367 | $grpClass.Location = new-object System.Drawing.Point(17, 86)
368 | $grpClass.Name = "grpClass"
369 | $grpClass.Size = new-object System.Drawing.Size(744, 198)
370 | $grpClass.TabIndex = 0
371 | $grpClass.TabStop = $False
372 | $grpClass.Text = "Class"
373 |
374 | #
375 | # btnInstances
376 | #
377 | $btnInstances.Anchor = "Bottom, Left"
378 | $btnInstances.Location = new-object System.Drawing.Point(6, 169);
379 | $btnInstances.Name = "btnInstances";
380 | $btnInstances.Size = new-object System.Drawing.Size(96, 23);
381 | $btnInstances.TabIndex = 0;
382 | $btnInstances.Text = "Get Instances";
383 | $btnInstances.UseVisualStyleBackColor = $true
384 | #
385 | # grpStatus
386 | #
387 | $grpStatus.Anchor = "Top,Left,Right"
388 | $grpStatus.Controls.Add($lblClasses)
389 | $grpStatus.Controls.Add($label12)
390 | $grpStatus.Controls.Add($lblNameSpace)
391 | $grpStatus.Controls.Add($label6)
392 | $grpStatus.Controls.Add($lblPath)
393 | $grpStatus.Controls.Add($lblServer)
394 | $grpStatus.Controls.Add($label2)
395 | $grpStatus.Controls.Add($label1)
396 | $grpStatus.Location = new-object System.Drawing.Point(17, 3)
397 | $grpStatus.Name = "grpStatus"
398 | $grpStatus.Size = new-object System.Drawing.Size(744, 77)
399 | $grpStatus.TabIndex = 1
400 | $grpStatus.TabStop = $False
401 | $grpStatus.Text = "Status"
402 | #
403 | # label1
404 | #
405 | $label1.AutoSize = $true
406 | $label1.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
407 | $label1.Location = new-object System.Drawing.Point(7, 20)
408 | $label1.Name = "label1"
409 | $label1.Size = new-object System.Drawing.Size(62, 16)
410 | $label1.TabIndex = 0
411 | $label1.Text = "Server :"
412 | #
413 | # label2
414 | #
415 | $label2.AutoSize = $true
416 | $label2.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
417 | $label2.Location = new-object System.Drawing.Point(7, 41)
418 | $label2.Name = "label2"
419 | $label2.Size = new-object System.Drawing.Size(51, 16)
420 | $label2.TabIndex = 1
421 | $label2.Text = "Path :"
422 | #
423 | # lblServer
424 | #
425 | $lblServer.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
426 | $lblServer.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
427 | $lblServer.Location = new-object System.Drawing.Point(75, 20)
428 | $lblServer.Name = "lblServer"
429 | $lblServer.Size = new-object System.Drawing.Size(144, 20)
430 | $lblServer.TabIndex = 2
431 | #
432 | # lblPath
433 | #
434 | $lblPath.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
435 | $lblPath.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
436 | $lblPath.Location = new-object System.Drawing.Point(75, 40)
437 | $lblPath.Name = "lblPath"
438 | $lblPath.Size = new-object System.Drawing.Size(567, 20)
439 | $lblPath.TabIndex = 3
440 | #
441 | # lblNameSpace
442 | #
443 | $lblNameSpace.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
444 | $lblNameSpace.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
445 | $lblNameSpace.Location = new-object System.Drawing.Point(337, 20)
446 | $lblNameSpace.Name = "lblNameSpace"
447 | $lblNameSpace.Size = new-object System.Drawing.Size(144, 20)
448 | $lblNameSpace.TabIndex = 5
449 | #
450 | # label6
451 | #
452 | $label6.AutoSize = $true
453 | $label6.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
454 | $label6.Location = new-object System.Drawing.Point(229, 20)
455 | $label6.Name = "label6"
456 | $label6.Size = new-object System.Drawing.Size(102, 16)
457 | $label6.TabIndex = 4
458 | $label6.Text = "NameSpace :"
459 | #
460 | # lblClass
461 | #
462 | $lblClass.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
463 | $lblClass.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
464 | $lblClass.Location = new-object System.Drawing.Point(110, 26)
465 | $lblClass.Name = "lblClass"
466 | $lblClass.Size = new-object System.Drawing.Size(159, 20)
467 | $lblClass.TabIndex = 11
468 | #
469 | # label10
470 | #
471 | $label10.AutoSize = $true
472 | $label10.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
473 | $label10.Location = new-object System.Drawing.Point(6, 26)
474 | $label10.Name = "label10"
475 | $label10.Size = new-object System.Drawing.Size(55, 16)
476 | $label10.TabIndex = 10
477 | $label10.Text = "Class :"
478 | #
479 | # lblClasses
480 | #
481 | $lblClasses.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
482 | $lblClasses.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
483 | $lblClasses.Location = new-object System.Drawing.Point(595, 21)
484 | $lblClasses.Name = "lblClasses"
485 | $lblClasses.Size = new-object System.Drawing.Size(47, 20)
486 | $lblClasses.TabIndex = 9
487 | #
488 | # label12
489 | #
490 | $label12.AutoSize = $true
491 | $label12.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
492 | $label12.Location = new-object System.Drawing.Point(487, 21)
493 | $label12.Name = "label12"
494 | $label12.Size = new-object System.Drawing.Size(76, 16)
495 | $label12.TabIndex = 8
496 | $label12.Text = "Classes :"
497 | #
498 | # clbProperties
499 | #
500 | $clbProperties.Anchor = "Bottom, top,left"
501 | $clbProperties.FormattingEnabled = $true
502 | $clbProperties.Location = new-object System.Drawing.Point(510, 27)
503 | $clbProperties.Name = "clbProperties"
504 | $clbProperties.Size = new-object System.Drawing.Size(220, 160)
505 | $clbProperties.TabIndex = 1
506 | #
507 | # lbMethods
508 | #
509 | $lbMethods.Anchor = "Bottom, top, Left"
510 | $lbMethods.FormattingEnabled = $true
511 | $lbMethods.Location = new-object System.Drawing.Point(280, 27)
512 | $lbMethods.Name = "lbMethods"
513 | $lbMethods.Size = new-object System.Drawing.Size(220, 160)
514 | $lbMethods.TabIndex = 2
515 | #
516 | # lblProperties
517 | #
518 | $lblProperties.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
519 | $lblProperties.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
520 | $lblProperties.Location = new-object System.Drawing.Point(110, 46)
521 | $lblProperties.Name = "lblProperties"
522 | $lblProperties.Size = new-object System.Drawing.Size(119, 20)
523 | $lblProperties.TabIndex = 13
524 | #
525 | # label8
526 | #
527 | $label8.AutoSize = $true
528 | $label8.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
529 | $label8.Location = new-object System.Drawing.Point(6, 46)
530 | $label8.Name = "label8"
531 | $label8.Size = new-object System.Drawing.Size(88, 16)
532 | $label8.TabIndex = 12
533 | $label8.Text = "Properties :"
534 | #
535 | # lblMethods
536 | #
537 | $lblMethods.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
538 | $lblMethods.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
539 | $lblMethods.Location = new-object System.Drawing.Point(110, 66)
540 | $lblMethods.Name = "lblMethods"
541 | $lblMethods.Size = new-object System.Drawing.Size(119, 20)
542 | $lblMethods.TabIndex = 15
543 | #
544 | # label14
545 | #
546 | $label14.AutoSize = $true
547 | $label14.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
548 | $label14.Location = new-object System.Drawing.Point(6, 66)
549 | $label14.Name = "label14"
550 | $label14.Size = new-object System.Drawing.Size(79, 16)
551 | $label14.TabIndex = 14
552 | $label14.Text = "Methods :"
553 | #
554 | # lblInstances
555 | #
556 | $lblInstances.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
557 | $lblInstances.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
558 | $lblInstances.Location = new-object System.Drawing.Point(110, 86)
559 | $lblInstances.Name = "lblInstances"
560 | $lblInstances.Size = new-object System.Drawing.Size(119, 20)
561 | $lblInstances.TabIndex = 17
562 | #
563 | # label16
564 | #
565 | $label16.AutoSize = $true
566 | $label16.Font = new-object System.Drawing.Font("Microsoft Sans Serif",9.75 ,[System.Drawing.FontStyle]::Bold)
567 | $label16.Location = new-object System.Drawing.Point(6, 86)
568 | $label16.Name = "label16"
569 | $label16.Size = new-object System.Drawing.Size(82, 16)
570 | $label16.TabIndex = 16
571 | $label16.Text = "Instances :"
572 | #
573 | # grpInstances
574 | #
575 | $grpInstances.Anchor = "Bottom, top, left, right"
576 | $grpInstances.Controls.Add($dgInstances)
577 | $grpInstances.Location = new-object System.Drawing.Point(17, 17)
578 | $grpInstances.Name = "grpInstances"
579 | $grpInstances.Size = new-object System.Drawing.Size(744, 202)
580 | $grpInstances.TabIndex = 0
581 | $grpInstances.TabStop = $False
582 | $grpInstances.Text = "Instances"
583 | #
584 | # dgInstances
585 | #
586 | $dgInstances.Anchor = "Bottom, top, left, right"
587 |
588 | $dgInstances.ColumnHeadersHeightSizeMode = [System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode]::AutoSize
589 | $dgInstances.Location = new-object System.Drawing.Point(10, 19)
590 | $dgInstances.Name = "dgInstances"
591 | $dgInstances.Size = new-object System.Drawing.Size(728, 167)
592 | $dgInstances.TabIndex = 0
593 | $dginstances.ReadOnly = $true
594 |
595 | # TabControl
596 | #
597 | $TabControl.Controls.Add($tabPage1)
598 | $TabControl.Controls.Add($tabInstances)
599 | $TabControl.Controls.Add($tabMethods)
600 | $TabControl.Dock = [System.Windows.Forms.DockStyle]::Fill
601 | $TabControl.Location = new-object System.Drawing.Point(0, 0)
602 | $TabControl.Name = "TabControl"
603 | $TabControl.SelectedIndex = 0
604 | $TabControl.Size = new-object System.Drawing.Size(771, 234)
605 | $TabControl.TabIndex = 0
606 | #
607 | # tabPage1
608 | #
609 | $tabPage1.Controls.Add($rtbHelp)
610 | $tabPage1.Location = new-object System.Drawing.Point(4, 22)
611 | $tabPage1.Name = "tabPage1"
612 | $tabPage1.Padding = new-object System.Windows.Forms.Padding(3)
613 | $tabPage1.Size = new-object System.Drawing.Size(763, 208)
614 | $tabPage1.TabIndex = 0
615 | $tabPage1.Text = "Help"
616 | $tabPage1.UseVisualStyleBackColor = $true
617 | #
618 | # tabInstances
619 | #
620 | $tabInstances.Controls.Add($grpInstances)
621 | $tabInstances.Location = new-object System.Drawing.Point(4, 22)
622 | $tabInstances.Name = "tabInstances"
623 | $tabInstances.Padding = new-object System.Windows.Forms.Padding(3)
624 | $tabInstances.Size = new-object System.Drawing.Size(763, 208)
625 | $tabInstances.TabIndex = 1
626 | $tabInstances.Text = "Instances"
627 | $tabInstances.UseVisualStyleBackColor = $true
628 | #
629 | # richTextBox1
630 | #
631 | $rtbHelp.Dock = [System.Windows.Forms.DockStyle]::Fill
632 | $rtbHelp.Location = new-object System.Drawing.Point(3, 3)
633 | $rtbHelp.Name = "richTextBox1"
634 | $rtbHelp.Size = new-object System.Drawing.Size(757, 202)
635 | $rtbHelp.TabIndex = 0
636 | $rtbHelp.Text = ""
637 | #
638 | # tabMethods
639 | #
640 | $tabMethods.Location = new-object System.Drawing.Point(4, 22)
641 | $tabMethods.Name = "tabMethods"
642 | $tabMethods.Padding = new-object System.Windows.Forms.Padding(3)
643 | $tabMethods.Size = new-object System.Drawing.Size(763, 208)
644 | $tabMethods.TabIndex = 2
645 | $tabMethods.Text = "Methods"
646 | $tabMethods.UseVisualStyleBackColor = $true
647 |
648 |
649 | $rtbMethods.Dock = [System.Windows.Forms.DockStyle]::Fill
650 | $rtbMethods.Font = new-object System.Drawing.Font("Lucida Console",8 )
651 | $rtbMethods.DetectUrls = $false
652 | $tabMethods.controls.add($rtbMethods)
653 |
654 | #endregion Configure Controls
655 |
656 | # Configure Main Form
657 |
658 | #region frmMain
659 |
660 |
661 | #
662 | $frmMain.AutoScaleDimensions = new-object System.Drawing.SizeF(6, 13)
663 | $frmMain.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
664 | $frmMain.ClientSize = new-object System.Drawing.Size(1151, 591)
665 | $frmMain.Controls.Add($splitContainer1)
666 | $frmMain.Controls.Add($statusStrip)
667 | $frmMain.Controls.Add($MainMenu)
668 | $frmMain.MainMenuStrip = $mainMenu
669 | $FrmMain.Name = "frmMain"
670 | $FrmMain.Text = "/\/\o\/\/ PowerShell WMI Browser"
671 | $mainMenu.ResumeLayout($false)
672 | $mainMenu.PerformLayout()
673 | $MainMenu.ResumeLayout($false)
674 | $MainMenu.PerformLayout()
675 | $splitContainer1.Panel1.ResumeLayout($false)
676 | $splitContainer1.Panel2.ResumeLayout($false)
677 | $splitContainer1.ResumeLayout($false)
678 | $splitContainer2.Panel1.ResumeLayout($false)
679 | $splitContainer2.Panel2.ResumeLayout($false)
680 | $splitContainer2.ResumeLayout($false)
681 | $grpComputer.ResumeLayout($false)
682 | $grpComputer.PerformLayout()
683 | $grpNameSpaces.ResumeLayout($false)
684 | $grpClasses.ResumeLayout($false)
685 | $splitContainer3.Panel1.ResumeLayout($false)
686 | $splitContainer3.Panel2.ResumeLayout($false)
687 | $splitContainer3.ResumeLayout($false)
688 | $grpClass.ResumeLayout($false)
689 | $grpClass.PerformLayout()
690 | $grpStatus.ResumeLayout($false)
691 | $grpStatus.PerformLayout()
692 | $grpInstances.ResumeLayout($false)
693 | $TabControl.ResumeLayout($false)
694 | $tabPage1.ResumeLayout($false)
695 | $tabInstances.ResumeLayout($false)
696 | $frmMain.ResumeLayout($false)
697 | $FrmMain.PerformLayout()
698 |
699 | $status = new-object System.Windows.Forms.ToolStripStatusLabel
700 | $status.BorderStyle = 'SunkenInner'
701 | $status.BorderSides = 'All'
702 | $status.Text = "Not Connected"
703 | [void]$statusStrip.Items.add($status)
704 | $slMessage = new-object System.Windows.Forms.ToolStripStatusLabel
705 | $slMessage.BorderStyle = 'SunkenInner'
706 | $slMessage.BorderSides = 'All'
707 | $slMessage.Text = ""
708 | [void]$statusStrip.Items.add($slMessage)
709 | #endregion frmMain
710 | #endregion
711 |
712 | #region Helper Functions
713 |
714 | Function out-PropertyGrid {
715 | Param ($Object,[switch]$noBase,[Switch]$array)
716 |
717 | $PsObject = $null
718 | if ($object) {
719 | $PsObject = $object
720 | }Else{
721 | if ($Array.IsPresent) {
722 | $PsObject = @()
723 | $input |ForEach-Object {$PsObject += $_}
724 | }Else{
725 | $input |ForEach-Object {$PsObject = $_}
726 | }
727 | }
728 |
729 | if ($PsObject){
730 | $form = new-object Windows.Forms.Form
731 | $form.Size = new-object Drawing.Size @(600,600)
732 | $PG = new-object Windows.Forms.PropertyGrid
733 | $PG.Dock = 'Fill'
734 | $form.text = "$psObject"
735 |
736 | if ($noBase.IsPresent) {"no";
737 | $PG.selectedobject = $psObject
738 | }Else{
739 | $PG.selectedobject = $psObject.PsObject.baseobject
740 | }
741 | $form.Controls.Add($PG)
742 | $Form.Add_Shown({$form.Activate()})
743 | $form.showdialog()
744 | }
745 |
746 | } #Function out-PropertyGrid
747 |
748 | Function Update-Status {
749 | $script:computer = $Script:NameSpaces.__SERVER
750 | $txtComputer.Text = $script:computer
751 | $lblPath.Text = $Script:NameSpaces.__PATH
752 | $lblProperties.Text = $Script:NameSpaces.__PROPERTY_COUNT
753 | $lblClass.Text = $Script:NameSpaces.__RELPATH
754 | $lblServer.Text = $script:Computer
755 | $lblnamespace.Text = $Script:NameSpaces.__NAMESPACE
756 | } # Function Update-Status
757 |
758 | Function Set-StatusBar ($Color,$Text) {
759 | $status.BackColor = $color
760 | $status.Text = $text
761 | $statusstrip.Update()
762 | }
763 |
764 | #endregion Helper Functions
765 |
766 | #################### Main ###############################
767 |
768 | #region Global Variables
769 |
770 | $FontBold = new-object System.Drawing.Font("Microsoft Sans Serif",8,[Drawing.FontStyle]'Bold' )
771 | $fontNormal = new-object System.Drawing.Font("Microsoft Sans Serif",8,[Drawing.FontStyle]'Regular')
772 | $fontCode = new-object System.Drawing.Font("Lucida Console",8 )
773 |
774 | # Create Script Variables for WMI Connection
775 |
776 | $Script:ConnectionOptions = new-object System.Management.ConnectionOptions
777 | $script:WmiConnection = new-object system.management.ManagementScope
778 | $script:WmiClass = [wmiClass]''
779 |
780 | # NamespaceCaching , Make HashTable to store Treeview Items
781 |
782 | $script:nsc = @{}
783 |
784 | # Make DataSet for secondary Cache
785 |
786 | $Script:dsCache = new-object data.dataset
787 |
788 | if (-not ${Global:WmiExplorer.dtClasses}){
789 | ${Global:WmiExplorer.dtClasses} = new-object data.datatable
790 | [VOID](${Global:WmiExplorer.dtClasses}.Columns.add('Path',[string]))
791 | [VOID](${Global:WmiExplorer.dtClasses}.Columns.add('Namespace',[string]))
792 | [VOID](${Global:WmiExplorer.dtClasses}.Columns.add('name',[string]))
793 | [VOID](${Global:WmiExplorer.dtClasses}.Columns.add('Description',[string]))
794 | ${Global:WmiExplorer.dtClasses}.tablename = 'Classes'
795 | }
796 |
797 | #endregion
798 |
799 | #region Control Handlers
800 |
801 | # Add Delegate Scripts to finetune the WMI Connection objects to the events of the controls
802 |
803 | $slMessage.DoubleClickEnabled = $true
804 | $slMessage.add_DoubleClick({$error[0] | out-PropertyGrid})
805 | $lblNameSpace.add_DoubleClick({$script:WmiConnection | out-PropertyGrid})
806 | $lblserver.add_DoubleClick({$Script:ConnectionOptions | out-PropertyGrid})
807 | $lblClass.add_DoubleClick({$script:WmiClass | out-PropertyGrid})
808 |
809 |
810 | $btnConnect.add_click({ConnectToComputer})
811 | $TVNameSpaces.add_DoubleClick({GetClassesFromNameSpace})
812 | $lvClasses.Add_DoubleClick({GetWmiClass})
813 | $btnInstances.add_Click({GetWmiInstances})
814 | $dgInstances.add_DoubleClick({OutputWmiInstance})
815 | $lbMethods.Add_DoubleClick({GetWmiMethod})
816 |
817 | $clbProperties.add_Click({
818 | trap{Continue}
819 | $DGInstances.Columns.Item(($this.SelectedItem)).visible = -not $clbProperties.GetItemChecked($this.SelectedIndex)
820 |
821 | })
822 |
823 | $TVNameSpaces.add_AfterSelect({
824 |
825 | if ($this.SelectedNode.name -ne $Computer){
826 | $lblPath.Text = "$($script:WmiConnection.path.path.replace('\root',''))\$($this.SelectedNode.Text)"
827 | }
828 |
829 | $lblProperties.Text = $Script:NameSpaces.__PROPERTY_COUNT
830 | $lblServer.Text = $Script:NameSpaces.__SERVER
831 | $lblnamespace.Text = $this.SelectedNode.Text
832 |
833 | if ($this.SelectedNode.tag -eq "NotEnumerated") {
834 |
835 | (new-object system.management.managementClass(
836 | "$($script:WmiConnection.path.path.replace('\root',''))\$($this.SelectedNode.Text):__NAMESPACE")
837 | ).PSbase.getInstances() | Sort-Object $_.name |
838 | ForEach-Object {
839 | $TN = new-object System.Windows.Forms.TreeNode
840 | $TN.Name = $_.name
841 | $TN.Text = ("{0}\{1}" -f $_.__NameSpace,$_.name)
842 | $TN.tag = "NotEnumerated"
843 | $this.SelectedNode.Nodes.Add($TN)
844 | }
845 |
846 | # Set tag to show this node is already enumerated
847 | $this.SelectedNode.tag = "Enumerated"
848 | }
849 |
850 | $mp = ("{0}\{1}" -f $script:WmiConnection.path.path.replace('\root','') , $this.SelectedNode.text)
851 | $lvClasses.Items.Clear()
852 |
853 | if($Script:nsc.Item("$mp")){ # in Namespace cache
854 | $lvClasses.BeginUpdate()
855 | $lvClasses.Items.AddRange(($nsc.Item( "$mp")))
856 | $status.Text = "$mp : $($lvClasses.Items.count) Classes"
857 | $lvClasses.EndUpdate()
858 | $lblClasses.Text = $lvClasses.Items.count
859 | } else {
860 | if(${Global:WmiExplorer.dtClasses}.Select("Namespace='$mp'")){ # In DataTable Cache
861 | $status.BackColor = 'beige'
862 | $status.Text = "$mp : Classes in Cache, DoubleClick NameSpace to retrieve Classes"
863 | } else {
864 | $status.BackColor = 'LightSalmon'
865 | $status.Text = "$mp : Classes not recieved yet, DoubleClick NameSpace to retrieve Classes"
866 | }
867 | }
868 |
869 | }) # $TVNameSpaces.add_AfterSelect
870 |
871 | #endregion
872 |
873 | #region Processing Functions
874 |
875 | #region ConnectToComputer
876 | # Connect to Computer
877 | Function ConnectToComputer {
878 |
879 | $computer = $txtComputer.Text
880 | Set-StatusBar 'beige' "Connecting to : $computer"
881 |
882 | # Try to Connect to Computer
883 |
884 | &{
885 | trap {
886 | Set-StatusBar 'Red' "Connecting to : $computer Failed"
887 | $slMessage.Text = "$_.message"
888 | Continue
889 | }
890 |
891 | &{
892 | # Connect to WMI root
893 |
894 | $script:WmiConnection.path = "\\$computer\root"
895 | $script:WmiConnection.options = $Script:ConnectionOptions
896 | $script:WmiConnection.Connect()
897 |
898 | # Get Avaiable NameSpaces
899 |
900 | $opt = new-object system.management.ObjectGetOptions
901 | $opt.UseAmendedQualifiers = $true
902 |
903 | $Script:NameSpaces = new-object System.Management.ManagementClass(
904 | $script:WmiConnection,[Management.ManagementPath]'__Namespace',$opt
905 | )
906 |
907 | Update-Status
908 |
909 | # Create a TreeNode for the WMI Root found
910 |
911 | $computer = $txtComputer.Text
912 | $TNRoot = new-object System.Windows.Forms.TreeNode("Root")
913 | $TNRoot.Name = $Computer
914 | $TNRoot.Text = $lblPath.Text
915 | $TNRoot.tag = "Enumerated"
916 |
917 | # Create NameSpaces List
918 |
919 | $Script:NameSpaces.PSbase.getInstances() | Sort-Object $_.name |
920 | ForEach-Object {
921 | $TN = new-object System.Windows.Forms.TreeNode
922 | $TN.Name = $_.name
923 | $TN.Text = ("{0}\{1}" -f $_.__NameSpace,$_.name)
924 | $TN.tag = "NotEnumerated"
925 | [void]$TNRoot.Nodes.Add($TN)
926 | }
927 |
928 | # Add to Treeview
929 | $tvNameSpaces.Nodes.clear()
930 | [void]$TVNamespaces.Nodes.Add($TNRoot)
931 |
932 | # update StatusBar
933 |
934 | Set-StatusBar 'YellowGreen' "Connected to : $computer"
935 |
936 | }
937 | }
938 |
939 | } # ConnectToComputer
940 |
941 | #endregion
942 |
943 | #region GetClasseFromNameSpace
944 |
945 | # Get Classes on DoubleClick on Namespace in TreeView
946 |
947 | Function GetClassesFromNameSpace {
948 |
949 | if ($this.SelectedNode.name -ne $script:computer){
950 | # Connect to WMI Namespace
951 |
952 | $mp = ("{0}\{1}" -f $script:WmiConnection.path.path.replace('\root','') , $this.SelectedNode.text)
953 |
954 | # Update Status
955 |
956 | $lvClasses.BeginUpdate()
957 | $lvClasses.Items.Clear()
958 | $i = 0 ;$lblClasses.Text = $i; $lblclasses.Update()
959 |
960 | if($Script:nsc.Item("$mp")){ #in Namespace Cache, so just attach to ListView again
961 |
962 | $lvClasses.Items.AddRange(($nsc.Item( "$mp")))
963 | # $lvClasses.Items.AddRange(([System.Windows.Forms.ListViewItem[]]($nsc.Item( "$mp") |
964 | # where {$_.name -like 'win32_*'})))
965 | $status.Text = "$mp : $($lvClasses.Items.count) Classes"
966 | $i = $lvClasses.Items.count
967 | } else { #Not In NameSpace Cache
968 |
969 | if(${Global:WmiExplorer.dtClasses}.Select("Namespace = '$mp'")){ # In DataTable cache, so get from there
970 |
971 | $status.Text = "loading cache from $($this.SelectedNode.name)"
972 | $statusStrip.Update()
973 |
974 | ${Global:WmiExplorer.dtClasses}.Select("Namespace = '$mp'") |
975 | foreach {
976 | $i++
977 | $LI = New-Object system.Windows.Forms.ListViewItem
978 | $li.Name = $_.name
979 | $li.Text = $_.name
980 | $li.SubItems.add($_.description)
981 | $li.SubItems.add($_.path)
982 | $li.ToolTipText = ($_.description)
983 | $lvClasses.Items.add($li)
984 | $status.Text = "$mp : $($lvClasses.Items.count) Classes"
985 | $lblClasses.Text = $lvClasses.Items.count
986 | }
987 |
988 | } else { # Not in any Cache , Load WMI Classes
989 |
990 | Set-StatusBar 'Khaki' "Getting Classes from $($this.SelectedNode.name)"
991 |
992 | $mc = new-object System.Management.ManagementClass($mp,$opt)
993 | $eo = New-Object system.management.EnumerationOptions
994 | $eo.EnumerateDeep = $true
995 | $eo.UseAmendedQualifiers = $true
996 |
997 | $Mc.psbase.GetSubclasses($eo) |
998 | ForEach-Object {
999 | $i++ ; if ($i%10 -eq 0){$lblClasses.Text = $i;$lblclasses.Update() }
1000 | Trap{$script:Description = "[Empty]";continue}
1001 | $script:description = $_.psbase.Qualifiers.item("description").value
1002 | ${Global:WmiExplorer.dtClasses}.Rows.Add($_.__path,$mp,$_.name,$description)
1003 | $LI = New-Object system.Windows.Forms.ListViewItem
1004 | $li.Name = $_.name
1005 | $li.Text = $_.name
1006 | $li.SubItems.add($description)
1007 | $li.SubItems.add($_.__path)
1008 | $li.ToolTipText = $description
1009 | $lvClasses.Items.add($li)
1010 | }
1011 |
1012 | $status.Text = "Ready, Retrieved $i Classes from $mp"
1013 |
1014 | } #if(${Global:WmiExplorer.dtClasses}.Select("Namespace = '$mp'"))
1015 |
1016 | $lvClasses.Sorting = 'Ascending'
1017 | $lvClasses.Sort()
1018 | $script:nsc.Add($mp,(([System.Windows.Forms.ListViewItem[]]($lvClasses.Items)).clone()))
1019 |
1020 | }
1021 |
1022 | $lvClasses.EndUpdate()
1023 | $this.selectedNode.BackColor = 'AliceBlue'
1024 | $lblClasses.Text = $i;$lblclasses.Update()
1025 | $status.BackColor = 'YellowGreen'
1026 | $statusStrip.Update()
1027 |
1028 | } #if($Script:nsc.Item("$mp"))
1029 |
1030 | } # GetClassesFromNameSpace
1031 | #endregion
1032 |
1033 | #region GetWmiClass
1034 | Function GetWmiClass {
1035 |
1036 | # Update Status
1037 |
1038 | $status.Text = "Retrieving Class"
1039 | $status.BackColor = 'Khaki'
1040 | $statusstrip.Update()
1041 | $lblClass.Text = $this.SelectedItems |ForEach-Object {$_.name}
1042 | $lblPath.text = $this.SelectedItems |ForEach-Object {"$($_.SubItems[2].text)"}
1043 |
1044 | # Add HelpText
1045 |
1046 | $rtbHelp.Text = ""
1047 | $rtbHelp.selectionFont = $fontBold
1048 | $rtbHelp.appendtext("$($lblClass.Text)`n`n")
1049 | $rtbHelp.selectionFont = $fontNormal
1050 | $rtbHelp.appendtext(($this.SelectedItems |ForEach-Object {"$($_.SubItems[1].text)"}))
1051 | $rtbHelp.appendtext("`n")
1052 | $path = $lblPath.text
1053 |
1054 | $opt = new-object system.management.ObjectGetOptions
1055 | $opt.UseAmendedQualifiers = $true
1056 |
1057 | $script:WmiClass = new-object system.management.ManagementClass($path,$opt)
1058 |
1059 | # Add Property Help
1060 |
1061 | $rtbHelp.selectionFont = $fontBold
1062 | $rtbHelp.appendtext("`n$($lblClass.Text) Properties :`n`n")
1063 | $rtbHelp.selectionFont = $fontNormal
1064 |
1065 | $i = 0 ;$lblProperties.Text = $i; $lblProperties.Update()
1066 | $clbproperties.Items.Clear()
1067 | $clbProperties.Items.add('WmiPath',$False)
1068 |
1069 | $script:WmiClass.psbase.properties |
1070 | ForEach-Object {
1071 | $i++ ;$lblProperties.Text = $i; $lblProperties.Update()
1072 | $clbProperties.Items.add($_.name,$true)
1073 | $rtbHelp.selectionFont = $fontBold
1074 | $rtbHelp.appendtext("$($_.Name) :`n" )
1075 | &{
1076 | Trap {$rtbHelp.appendtext("[Empty]");Continue}
1077 | $rtbHelp.appendtext($_.psbase.Qualifiers["description"].value)
1078 | }
1079 | $rtbHelp.appendtext("`n`n")
1080 | } # ForEach-Object
1081 |
1082 |
1083 | # Create Method Help
1084 |
1085 | $rtbHelp.selectionFont = $fontBold
1086 | $rtbHelp.appendtext( "$($lblClass.Text) Methods :`n`n" )
1087 |
1088 | $i = 0 ;$lblMethods.Text = $i; $lblMethods.Update()
1089 | $lbmethods.Items.Clear()
1090 |
1091 | $script:WmiClass.psbase.Methods |
1092 | ForEach-Object {
1093 | $i++ ;$lblMethods.Text = $i; $lblMethods.Update()
1094 | $lbMethods.Items.add($_.name)
1095 | $rtbHelp.selectionFont = $fontBold
1096 | $rtbHelp.appendtext("$($_.Name) :`n")
1097 | &{
1098 | Trap {$rtbHelp.Text += "[Empty]"}
1099 | $rtbHelp.appendtext($_.Qualifiers["description"].value)
1100 | }
1101 | $rtbHelp.appendtext("`n`n" )
1102 | } #ForEach-Object
1103 |
1104 | $tabControl.SelectedTab = $tabpage1
1105 | $status.Text = "Retrieved Class"
1106 | $status.BackColor = 'YellowGreen'
1107 | $statusstrip.Update()
1108 |
1109 | } # GetWmiClass
1110 |
1111 | #endregion
1112 |
1113 | #region GetWmiInstances
1114 |
1115 | Function GetWmiInstances {
1116 |
1117 | $status.Text = "Getting Instances for $($lblClass.text)"
1118 | $status.BackColor = 'Red'
1119 | $statusstrip.Update()
1120 |
1121 | $tabControl.SelectedTab = $tabInstances
1122 |
1123 | $MC = new-object system.management.ManagementClass $lblPath.text
1124 | $MOC = $MC.PSbase.getInstances()
1125 |
1126 | #trap{"Class Not found";break}
1127 |
1128 | $DT = new-object System.Data.DataTable
1129 | $DT.TableName = $lblClass.text
1130 | $Col = new-object System.Data.DataColumn
1131 | $Col.ColumnName = "WmiPath"
1132 | $DT.Columns.Add($Col)
1133 |
1134 | $i = 0
1135 | $j = 0 ;$lblInstances.Text = $j; $lblInstances.Update()
1136 | $MOC | ForEach-Object {
1137 | $j++ ;$lblInstances.Text = $j; $lblInstances.Update()
1138 | $MO = $_
1139 |
1140 | # Make a DataRow
1141 | $DR = $DT.NewRow()
1142 | $Col = new-object System.Data.DataColumn
1143 |
1144 | $DR.Item("WmiPath") = $mo.__PATH
1145 |
1146 | $MO.psbase.properties |
1147 | ForEach-Object {
1148 | $prop = $_
1149 | If ($i -eq 0) {
1150 |
1151 | # Only On First Row make The Headers
1152 |
1153 | $Col = new-object System.Data.DataColumn
1154 | $Col.ColumnName = $prop.Name.ToString()
1155 | $prop.psbase.Qualifiers | ForEach-Object {
1156 | If ($_.Name.ToLower() -eq "key") {
1157 | $Col.ColumnName = $Col.ColumnName + "*"
1158 | }
1159 | }
1160 | $DT.Columns.Add($Col)
1161 | }
1162 |
1163 | # fill dataRow
1164 |
1165 | if ($prop.value -eq $null) {
1166 | $DR.Item($prop.Name) = "[empty]"
1167 | }
1168 | ElseIf ($prop.IsArray) {
1169 | $ofs = ";"
1170 | $DR.Item($prop.Name) ="$($prop.value)"
1171 | $ofs = $null
1172 | }
1173 | Else {
1174 | $DR.Item($prop.Name) = $prop.value
1175 | #Item is Key try again with *
1176 | trap{$DR.Item("$($prop.Name)*") = $prop.Value.tostring();continue}
1177 | }
1178 |
1179 | }
1180 |
1181 | # Add the row to the DataTable
1182 |
1183 | $DT.Rows.Add($DR)
1184 | $i += 1
1185 |
1186 | }
1187 |
1188 | $DGInstances.DataSource = $DT.psObject.baseobject
1189 | $DGInstances.Columns.Item('WmiPath').visible = $clbProperties.GetItemChecked(0)
1190 | $status.Text = "Retrieved $j Instances"
1191 | $status.BackColor = 'YellowGreen'
1192 | $statusstrip.Update()
1193 |
1194 | } # GetWmiInstances
1195 |
1196 | #endregion
1197 |
1198 | #region OutputWmiInstance
1199 | Function OutputWmiInstance {
1200 | if ( $this.SelectedRows.count -eq 1 ) {
1201 | if (-not $Script:InstanceTab) {$Script:InstanceTab = new-object System.Windows.Forms.TabPage
1202 | $Script:InstanceTab.Name = 'Instance'
1203 | $Script:rtbInstance = new-object System.Windows.Forms.RichTextBox
1204 | $Script:rtbInstance.Dock = [System.Windows.Forms.DockStyle]::Fill
1205 | $Script:rtbInstance.Font = $fontCode
1206 | $Script:rtbInstance.DetectUrls = $false
1207 | $Script:InstanceTab.controls.add($Script:rtbInstance)
1208 | $TabControl.TabPages.add($Script:InstanceTab)
1209 | }
1210 |
1211 | $Script:InstanceTab.Text = "Instance = $($this.SelectedRows | ForEach-Object {$_.DataboundItem.wmiPath.split(':')[1]})"
1212 | $Script:rtbInstance.Text = $this.SelectedRows |ForEach-Object {$_.DataboundItem |Format-List * | out-String -width 1000 }
1213 | $tabControl.SelectedTab = $Script:InstanceTab
1214 | }
1215 |
1216 | } # OutputWmiInstance
1217 |
1218 | #endregion
1219 |
1220 | #region GetWmiMethod
1221 |
1222 | Function GetWmiMethod {
1223 |
1224 | $WMIMethod = $this.SelectedItem
1225 | $WmiClassName = $script:WmiClass.__Class
1226 |
1227 | $tabControl.SelectedTab = $tabMethods
1228 | #$rtbmethods.ForeColor = 'Green'
1229 | $rtbMethods.Font = new-object System.Drawing.Font("Microsoft Sans Serif",8)
1230 | $rtbMethods.text = ""
1231 |
1232 | $rtbMethods.selectionFont = $fontBold
1233 |
1234 | $rtbMethods.AppendText(("{1} Method : {0} `n" -f $this.SelectedItem , $script:WmiClass.__Class))
1235 | $rtbMethods.AppendText("`n")
1236 |
1237 | $rtbMethods.selectionFont = $fontBold
1238 | $rtbMethods.AppendText("OverloadDefinitions:`n")
1239 | $rtbMethods.AppendText("$($script:WmiClass.$WMIMethod.OverloadDefinitions)`n`n")
1240 |
1241 | $Qualifiers=@()
1242 | $script:WmiClass.psbase.Methods[($this.SelectedItem)].Qualifiers | ForEach-Object {$qualifiers += $_.name}
1243 | #$rtbMethods.AppendText( "$qualifiers`n" )
1244 | $static = $Qualifiers -Contains "Static"
1245 |
1246 | $rtbMethods.selectionFont = $fontBold
1247 | $rtbMethods.AppendText( "Static : $static`n" )
1248 |
1249 | If ($static) {
1250 |
1251 | $rtbMethods.AppendText( "A Static Method does not an Instance to act upon`n`n" )
1252 | $rtbMethods.AppendText("`n")
1253 |
1254 | $rtbMethods.SelectionColor = 'Green'
1255 | $rtbMethods.SelectionFont = $fontCode
1256 | $rtbMethods.AppendText("# Sample Of Connecting to a WMI Class`n`n")
1257 | $rtbMethods.SelectionColor = 'Black'
1258 | $rtbMethods.SelectionFont = $fontCode
1259 |
1260 | $SB = new-Object text.stringbuilder
1261 | $SB = $SB.Append('$Computer = "') ; $SB = $SB.AppendLine(".`"")
1262 | $SB = $SB.Append('$Class = "') ; $SB = $SB.AppendLine("$WmiClassName`"")
1263 | $SB = $SB.Append('$Method = "') ; $SB = $SB.AppendLine("$WmiMethod`"`n")
1264 | $SB = $SB.AppendLine('$MC = [WmiClass]"\\$Computer\' + "$($script:WmiClass.__NAMESPACE)" + ':$Class"')
1265 | #$SB = $SB.Append('$MP.Server = "') ; $SB = $SB.AppendLine("$($MP.Server)`"")
1266 | #$SB = $SB.Append('$MP.NamespacePath = "') ; $SB = $SB.AppendLine("$($script:WmiClass.__NAMESPACE)`"")
1267 | #$SB = $SB.AppendLine('$MP.ClassName = $Class')
1268 | $SB = $SB.AppendLine("`n")
1269 | #$SB = $SB.AppendLine('$MC = new-object system.management.ManagementClass($MP)')
1270 | $rtbMethods.AppendText(($sb.tostring()))
1271 | $rtbMethods.SelectionColor = 'Green'
1272 | $rtbMethods.SelectionFont = $fontCode
1273 | $rtbMethods.AppendText("# Getting information about the methods`n`n")
1274 | $rtbMethods.SelectionColor = 'Black'
1275 | $rtbMethods.SelectionFont = $fontCode
1276 | $rtbMethods.AppendText(
1277 | '$mc' + "`n" +
1278 | '$mc | Get-Member -membertype Method' + "`n" +
1279 | "`$mc.$WmiMethod"
1280 | )
1281 |
1282 | } Else {
1283 |
1284 | $rtbMethods.AppendText( "This is a non Static Method and needs an Instance to act upon`n`n" )
1285 | $rtbMethods.AppendText( "The Example given will use the Key Properties to Connect to a WMI Instance : `n`n" )
1286 | $rtbMethods.SelectionColor = 'Green'
1287 | $rtbMethods.SelectionFont = $fontCode
1288 | $rtbMethods.AppendText("# Example Of Connecting to an Instance`n`n")
1289 |
1290 | $rtbMethods.SelectionColor = 'Black'
1291 | $rtbMethods.SelectionFont = $fontCode
1292 | $SB = new-Object text.stringbuilder
1293 | $SB = $SB.AppendLine('$Computer = "."')
1294 | $SB = $SB.Append('$Class = "') ; $SB = $SB.AppendLine("$WmiClassName.`"")
1295 | $SB = $SB.Append('$Method = "') ; $SB = $SB.AppendLine("$WMIMethod`"")
1296 | $SB = $SB.AppendLine("`n# $WmiClassName. Key Properties :")
1297 |
1298 | $Filter = ""
1299 | $script:WmiClass.psbase.Properties | ForEach-Object {
1300 | $Q = @()
1301 | $_.psbase.Qualifiers | ForEach-Object {$Q += $_.name}
1302 |
1303 | $key = $Q -Contains "key"
1304 | If ($key) {
1305 | $CIMType = $_.psbase.Qualifiers["Cimtype"].Value
1306 | $SB = $SB.AppendLine("`$$($_.Name) = [$CIMType]")
1307 | $Filter += "$($_.name) = `'`$$($_.name)`'"
1308 | }
1309 | }
1310 |
1311 | $SB = $SB.Append("`n" + '$filter=');$SB = $SB.AppendLine("`"$filter`"")
1312 | $SB = $SB.AppendLine('$MC = get-WMIObject $class -computer $Computer -Namespace "' +
1313 | "$($script:WmiClass.__NAMESPACE)" + '" -filter $filter' + "`n")
1314 | $SB = $SB.AppendLine('# $MC = [Wmi]"\\$Computer\Root\CimV2:$Class.$filter"')
1315 | $rtbMethods.AppendText(($sb.tostring()))
1316 |
1317 | }
1318 |
1319 | $SB = $SB.AppendLine('$InParams = $mc.psbase.GetMethodParameters($Method)')
1320 | $SB = $SB.AppendLine("`n")
1321 |
1322 | # output Method Parameter Help
1323 |
1324 | $rtbMethods.selectionFont = $fontBold
1325 | $rtbMethods.AppendText("`n`n$WmiClassName. $WMIMethod Method :`n`n")
1326 |
1327 | $q = $script:WmiClass.PSBase.Methods[$WMIMethod].Qualifiers | foreach {$_.name}
1328 |
1329 | if ($q -contains "Description") {
1330 | $rtbMethods.AppendText(($script:WmiClass.psbase.Methods[$WMIMethod].psbase.Qualifiers["Description"].Value))
1331 | }
1332 |
1333 | $rtbMethods.selectionFont = $fontBold
1334 | $rtbMethods.AppendText("`n`n$WMIMethod Parameters :`n")
1335 |
1336 | # get the Parameters
1337 |
1338 | $inParam = $script:WmiClass.psbase.GetMethodParameters($WmiMethod)
1339 |
1340 | $HasParams = $False
1341 | if ($true) {
1342 | trap{$rtbMethods.AppendText('[None]') ;continue}
1343 |
1344 | $inParam.PSBase.Properties | foreach {
1345 | $Q = $_.Qualifiers | foreach {$_.name}
1346 |
1347 | # if Optional Qualifier is not present then Parameter is Mandatory
1348 | $Optional = $q -contains "Optional"
1349 |
1350 | $CIMType = $_.Qualifiers["Cimtype"].Value
1351 | $rtbMethods.AppendText("`nName = $($_.Name) `nType = $CIMType `nOptional = $Optional")
1352 |
1353 | # write Parameters to Example script
1354 |
1355 | if ($Optional -eq $TRUE) {$SB = $SB.Append('# ')}
1356 | $SB = $SB.Append('$InParams.');$SB = $SB.Append("$($_.Name) = ");$SB = $SB.AppendLine("[$CIMType]")
1357 | if ($q -contains "Description") {$rtbMethods.AppendText($_.Qualifiers["Description"].Value)}
1358 | $HasParams = $true
1359 | }
1360 | }
1361 |
1362 | # Create the Rest of the Script
1363 |
1364 | $rtbMethods.selectionFont = $fontBold
1365 | $rtbMethods.AppendText("`n`nTemplate Script :`n")
1366 |
1367 | # Call diferent Overload as Method has No Parameters
1368 |
1369 | If ($HasParams -eq $True) {
1370 | $SB = $SB.AppendLine("`n`"Calling $WmiClassName. : $WMIMethod with Parameters :`"")
1371 | $SB = $SB.AppendLine('$inparams.PSBase.properties | select name,Value | format-Table')
1372 | $SB = $SB.AppendLine("`n" + '$R = $mc.PSBase.InvokeMethod($Method, $inParams, $Null)')
1373 | }Else{
1374 | $SB = $SB.AppendLine("`n`"Calling $WmiClassName. : $WMIMethod `"")
1375 | $SB = $SB.AppendLine("`n" + '$R = $mc.PSBase.InvokeMethod($Method,$Null)')
1376 | }
1377 |
1378 | $SB = $SB.AppendLine('"Result :"')
1379 | $SB = $SB.AppendLine('$R | Format-list' + "`n`n")
1380 |
1381 | # Write Header of the Sample Script :
1382 |
1383 | $rtbMethods.SelectionColor = 'Green'
1384 | $rtbMethods.SelectionFont = $fontCode
1385 |
1386 | $rtbMethods.AppendText(@"
1387 |
1388 | # $WmiClassName. $WMIMethod-Method Template Script"
1389 | # Created by PowerShell WmiExplorer
1390 | # /\/\o\/\/ 2006
1391 | # www.ThePowerShellGuy.com
1392 | #
1393 | # Fill InParams values before Executing
1394 | # InParams that are Remarked (#) are Optional
1395 | "@
1396 |
1397 | )
1398 |
1399 | $rtbMethods.SelectionColor = 'Black'
1400 | #$rtbMethods.SelectionFont = $fontCode
1401 | $rtbMethods.AppendText("`n`n" + $SB)
1402 |
1403 | $rtbMethods.SelectionFont = new-object System.Drawing.Font("Lucida Console",6 )
1404 | $rtbMethods.AppendText("`n`n Generated by the PowerShell WMI Explorer /\/\o\/\/ 2006" )
1405 |
1406 | } # GetWmiMethod
1407 |
1408 | #endregion
1409 |
1410 | #endregion
1411 |
1412 | # Show the Form
1413 |
1414 | $FrmMain.Add_Shown({$FrmMain.Activate()})
1415 |
1416 | trap {Write-Host $_ ;$status.Text = "unexpected error";$slMessage.Text = "$_.message";continue}
1417 |
1418 | & {
1419 | [void]$FrmMain.showdialog()
1420 | }
1421 |
1422 | # Resolve-Error $Error[0] | out-string
1423 |
1424 |
--------------------------------------------------------------------------------