├── ClockWidget.ps1
├── Convert-OutputForCSV.ps1
├── ConvertCSV-ToExcel.ps1
├── Get-ADGroupMemberDate.ps1
├── Get-Certificate.ps1
├── Get-ClientWSUSSetting.ps1
├── Get-ExchangeCachedMode.ps1
├── Get-FileHash.ps1
├── Get-GeoIP.ps1
├── Get-Icon.ps1
├── Get-LocalGroupMembership.ps1
├── Get-NetworkInfo.ps1
├── Get-PSSQLInstance.ps1
├── Get-PendingUpdate.ps1
├── Get-ProductKey.ps1
├── Get-SCCMClientUpdate.ps1
├── Get-ServiceStartModeEvent.ps1
├── Get-ServiceStateEvent.ps1
├── Get-TCPResponse.ps1
├── Get-USGSWaterData.ps1
├── Get-WebPage.ps1
├── Install-WSUSServer.ps1
├── Invoke-BalloonTip.ps1
├── Invoke-WSUSClientFixID.ps1
├── Invoke-WSUSDBMaintenance.ps1
├── LICENSE
├── New-SymLink.ps1
├── Out-Voice.ps1
├── README.md
├── Remove-LocalProfile.ps1
├── Set-ClientWSUSSetting.ps1
├── Set-Owner.ps1
├── Set-Password.ps1
├── Set-Window.ps1
├── Start-CountDownTimer.ps1
├── Test-IsAdmin.ps1
├── Test-Port-README.md
└── Test-Port.ps1
/ClockWidget.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYSNOPSIS
3 | Displays a clock on the screen with date.
4 |
5 | .DESCRIPTION
6 | Displays a clock on the screen with date.
7 |
8 | .PARAMETER TimeColor
9 | Specify the color of the time display.
10 |
11 | .PARAMETER DateColor
12 | Specify the color of the date display.
13 |
14 | Default is White
15 |
16 | .NOTES
17 | Author: Boe Prox
18 | Created: 27 March 2014
19 | Version History:
20 | Version 1.0 -- 27 March 2014
21 | -Initial build
22 |
23 | .EXAMPLE
24 | .\ClockWidget.ps1
25 |
26 | Description
27 | -----------
28 | Clock is displayed on screen
29 |
30 | .EXAMPLE
31 | .\ClockWidget.ps1 -TimeColor DarkRed -DateColor Gold
32 |
33 | Description
34 | -----------
35 | Clock is displayed on screen with alternate colors
36 |
37 | .EXAMPLE
38 | .\ClockWidget.ps1 –TimeColor "#669999" –DateColor "#334C4C"
39 |
40 | Description
41 | -----------
42 | Clock is displayed on screen with alternate colors as hex values
43 |
44 | #>
45 | Param (
46 | [parameter()]
47 | [string]$TimeColor = "White",
48 | [parameter()]
49 | [string]$DateColor = "White"
50 | )
51 | $Clockhash = [hashtable]::Synchronized(@{})
52 | $Runspacehash = [hashtable]::Synchronized(@{})
53 | $Runspacehash.host = $Host
54 | $Clockhash.TimeColor = $TimeColor
55 | $Clockhash.DateColor = $DateColor
56 | $Runspacehash.runspace = [RunspaceFactory]::CreateRunspace()
57 | $Runspacehash.runspace.ApartmentState = “STA”
58 | $Runspacehash.runspace.ThreadOptions = “ReuseThread”
59 | $Runspacehash.runspace.Open()
60 | $Runspacehash.psCmd = {Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase}.GetPowerShell()
61 | $Runspacehash.runspace.SessionStateProxy.SetVariable("Clockhash",$Clockhash)
62 | $Runspacehash.runspace.SessionStateProxy.SetVariable("Runspacehash",$Runspacehash)
63 | $Runspacehash.runspace.SessionStateProxy.SetVariable("TimeColor",$TimeColor)
64 | $Runspacehash.runspace.SessionStateProxy.SetVariable("DateColor",$DateColor)
65 | $Runspacehash.psCmd.Runspace = $Runspacehash.runspace
66 | $Runspacehash.Handle = $Runspacehash.psCmd.AddScript({
67 |
68 | $Script:Update = {
69 | $day,$Month, $Day_n, $Year, $Time, $AMPM = (Get-Date -f "dddd,MMMM,dd,yyyy,hh:mm,tt") -Split ','
70 |
71 | $Clockhash.time_txtbox.text = $Time.TrimStart("0")
72 | $Clockhash.day_txtbx.Text = $day
73 | $Clockhash.ampm_txtbx.text = $AMPM
74 | $Clockhash.day_n_txtbx.text = $Day_n
75 | $Clockhash.month_txtbx.text = $Month
76 | $Clockhash.year_txtbx.text = $year
77 | }
78 |
79 | [xml]$xaml = @"
80 |
85 |
86 |
88 |
89 |
90 |
91 |
92 |
94 |
95 |
96 |
97 |
98 |
100 |
101 |
102 |
103 |
104 |
106 |
107 |
108 |
109 |
110 |
112 |
113 |
114 |
115 |
116 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | "@
125 |
126 | $reader=(New-Object System.Xml.XmlNodeReader $xaml)
127 | $Clockhash.Window=[Windows.Markup.XamlReader]::Load( $reader )
128 |
129 | $Clockhash.time_txtbox = $Clockhash.window.FindName("time_txtbox")
130 | $Clockhash.ampm_txtbx = $Clockhash.Window.FindName("ampm_txtbx")
131 | $Clockhash.day_n_txtbx = $Clockhash.Window.FindName("day_n_txtbx")
132 | $Clockhash.month_txtbx = $Clockhash.Window.FindName("month_txtbx")
133 | $Clockhash.year_txtbx = $Clockhash.Window.FindName("year_txtbx")
134 | $Clockhash.day_txtbx = $Clockhash.Window.FindName("day_txtbx")
135 |
136 | #Timer Event
137 | $Clockhash.Window.Add_SourceInitialized({
138 | #Create Timer object
139 | Write-Verbose "Creating timer object"
140 | $Script:timer = new-object System.Windows.Threading.DispatcherTimer
141 | #Fire off every 1 minutes
142 | Write-Verbose "Adding 1 minute interval to timer object"
143 | $timer.Interval = [TimeSpan]"0:0:1.00"
144 | #Add event per tick
145 | Write-Verbose "Adding Tick Event to timer object"
146 | $timer.Add_Tick({
147 | $Update.Invoke()
148 | [Windows.Input.InputEventHandler]{ $Clockhash.Window.UpdateLayout() }
149 |
150 | })
151 | #Start timer
152 | Write-Verbose "Starting Timer"
153 | $timer.Start()
154 | If (-NOT $timer.IsEnabled) {
155 | $Clockhash.Window.Close()
156 | }
157 | })
158 |
159 | $Clockhash.Window.Add_Closed({
160 | $timer.Stop()
161 | $Runspacehash.PowerShell.Dispose()
162 |
163 | [gc]::Collect()
164 | [gc]::WaitForPendingFinalizers()
165 | })
166 | $Clockhash.month_txtbx.Add_SizeChanged({
167 | [int]$clockhash.length = [math]::Round(($Clockhash.day_txtbx.ActualWidth,$Clockhash.month_txtbx.ActualWidth |
168 | Sort -Descending)[0])
169 | [int]$Adjustment = $clockhash.length + 52 + 10 #Hard coded margin plus white space
170 |
171 | $YearMargin = $Clockhash.year_txtbx.Margin
172 | $Clockhash.year_txtbx.Margin = ("{0},{1},{2},{3}" -f ($Adjustment),
173 | $YearMargin.Top,$YearMargin.Right,$YearMargin.Bottom)
174 | })
175 | $Clockhash.time_txtbox.Add_SizeChanged({
176 | If ($Clockhash.time_txtbox.text.length -eq 4) {
177 | $Clockhash.ampm_txtbx.Margin = "133,0,86,0"
178 | } Else {
179 | $Clockhash.ampm_txtbx.Margin = "172,0,48,0"
180 | }
181 | })
182 | $Clockhash.Window.Add_MouseRightButtonUp({
183 | $This.close()
184 | })
185 | $Clockhash.Window.Add_MouseLeftButtonDown({
186 | $This.DragMove()
187 | })
188 | $Update.Invoke()
189 | $Clockhash.Window.ShowDialog() | Out-Null
190 | }).BeginInvoke()
--------------------------------------------------------------------------------
/Convert-OutputForCSV.ps1:
--------------------------------------------------------------------------------
1 | Function Convert-OutputForCSV {
2 | <#
3 | .SYNOPSIS
4 | Provides a way to expand collections in an object property prior
5 | to being sent to Export-Csv.
6 |
7 | .DESCRIPTION
8 | Provides a way to expand collections in an object property prior
9 | to being sent to Export-Csv. This helps to avoid the object type
10 | from being shown such as system.object[] in a spreadsheet.
11 |
12 | .PARAMETER InputObject
13 | The object that will be sent to Export-Csv
14 |
15 | .PARAMETER OutPropertyType
16 | This determines whether the property that has the collection will be
17 | shown in the CSV as a comma delimmited string or as a stacked string.
18 |
19 | Possible values:
20 | Stack
21 | Comma
22 |
23 | Default value is: Stack
24 |
25 | .NOTES
26 | Name: Convert-OutputForCSV
27 | Author: Boe Prox
28 | Created: 24 Jan 2014
29 | Version History:
30 | 1.1 - 02 Feb 2014
31 | -Removed OutputOrder parameter as it is no longer needed; inputobject order is now respected
32 | in the output object
33 | 1.0 - 24 Jan 2014
34 | -Initial Creation
35 |
36 | .EXAMPLE
37 | $Output = 'PSComputername','IPAddress','DNSServerSearchOrder'
38 |
39 | Get-WMIObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" |
40 | Select-Object $Output | Convert-OutputForCSV |
41 | Export-Csv -NoTypeInformation -Path NIC.csv
42 |
43 | Description
44 | -----------
45 | Using a predefined set of properties to display ($Output), data is collected from the
46 | Win32_NetworkAdapterConfiguration class and then passed to the Convert-OutputForCSV
47 | funtion which expands any property with a collection so it can be read properly prior
48 | to being sent to Export-Csv. Properties that had a collection will be viewed as a stack
49 | in the spreadsheet.
50 |
51 | #>
52 | #Requires -Version 3.0
53 | [cmdletbinding()]
54 | Param (
55 | [parameter(ValueFromPipeline)]
56 | [psobject]$InputObject,
57 | [parameter()]
58 | [ValidateSet('Stack','Comma')]
59 | [string]$OutputPropertyType = 'Stack'
60 | )
61 | Begin {
62 | $PSBoundParameters.GetEnumerator() | ForEach {
63 | Write-Verbose "$($_)"
64 | }
65 | $FirstRun = $True
66 | }
67 | Process {
68 | If ($FirstRun) {
69 | $OutputOrder = $InputObject.psobject.properties.name
70 | Write-Verbose "Output Order:`n $($OutputOrder -join ', ' )"
71 | $FirstRun = $False
72 | #Get properties to process
73 | $Properties = Get-Member -InputObject $InputObject -MemberType *Property
74 | #Get properties that hold a collection
75 | $Properties_Collection = @(($Properties | Where-Object {
76 | $_.Definition -match "Collection|\[\]"
77 | }).Name)
78 | #Get properties that do not hold a collection
79 | $Properties_NoCollection = @(($Properties | Where-Object {
80 | $_.Definition -notmatch "Collection|\[\]"
81 | }).Name)
82 | Write-Verbose "Properties Found that have collections:`n $(($Properties_Collection) -join ', ')"
83 | Write-Verbose "Properties Found that have no collections:`n $(($Properties_NoCollection) -join ', ')"
84 | }
85 |
86 | $InputObject | ForEach {
87 | $Line = $_
88 | $stringBuilder = New-Object Text.StringBuilder
89 | $Null = $stringBuilder.AppendLine("[pscustomobject] @{")
90 |
91 | $OutputOrder | ForEach {
92 | If ($OutputPropertyType -eq 'Stack') {
93 | $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$(($line.$($_) | Out-String).Trim())`"")
94 | } ElseIf ($OutputPropertyType -eq "Comma") {
95 | $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$($line.$($_) -join ', ')`"")
96 | }
97 | }
98 | $Null = $stringBuilder.AppendLine("}")
99 |
100 | Invoke-Expression $stringBuilder.ToString()
101 | }
102 | }
103 | End {}
104 | }
--------------------------------------------------------------------------------
/ConvertCSV-ToExcel.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/ConvertCSV-ToExcel.ps1
--------------------------------------------------------------------------------
/Get-ADGroupMemberDate.ps1:
--------------------------------------------------------------------------------
1 | Function Get-ADGroupMemberDate {
2 | <#
3 | .SYNOPSIS
4 | Provides the date that a member was added to a specified Active Directory group.
5 |
6 | .DESCRIPTION
7 | Provides the date that a member was added to a specified Active Directory group.
8 |
9 | .PARAMETER Group
10 | The group that will be inspected for members and date added. If a distinguished name (dn) is not used,
11 | an attempt to get the dn before making the query.
12 |
13 | .PARAMETER DomainController
14 | Name of the domain controller to query. Optional parameter.
15 |
16 | .NOTES
17 | Name: Get-ADGroupMemberDate
18 | Author: Boe Prox
19 | DateCreated: 17 May 2013
20 | Version 1.0
21 |
22 | The State property will be one of the following:
23 |
24 | PRESENT: User currently exists in group and the replicated using Linked Value Replication (LVR).
25 | ABSENT: User has been removed from group and has not been garbage collected based on Tombstone Lifetime (TSL).
26 | LEGACY: User currently exists as a member of the group but has no replication data via LVR.
27 |
28 | .EXAMPLE
29 | Get-ADGroupMemberDate -Group "Domain Admins" -DomainController DC3
30 |
31 | ModifiedCount : 2
32 | DomainController : DC3
33 | LastModified : 5/4/2013 6:48:06 PM
34 | Username : joesmith
35 | State : ABSENT
36 | Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
37 |
38 | ModifiedCount : 1
39 | DomainController : DC3
40 | LastModified : 1/6/2010 7:36:08 AM
41 | Username : adminuser
42 | State : PRESENT
43 | Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
44 | ...
45 |
46 | Description
47 | -----------
48 | This lists out all of the members of Domain Admins using DC3 as the Domain Controller.
49 |
50 | .EXAMPLE
51 | Get-ADGroup -Identity "TestGroup" | Get-ADGroupMemberDate
52 |
53 | ModifiedCount : 2
54 | DomainController : DC1
55 | LastModified : 5/4/2013 6:48:06 PM
56 | Username : joesmith
57 | State : ABSENT
58 | Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
59 |
60 | ModifiedCount : 1
61 | DomainController : DC1
62 | LastModified : 1/6/2010 7:36:08 AM
63 | Username : bobsmith
64 | State : PRESENT
65 | Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
66 | ...
67 |
68 | Description
69 | -----------
70 | This lists out all of the members of TestGroup from the output of Get-ADGroup and auto-selecting DC1 as the Domain Controller.
71 |
72 | #>
73 | [OutputType('ActiveDirectory.Group.Info')]
74 | [cmdletbinding()]
75 | Param (
76 | [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
77 | [Alias('DistinguishedName')]
78 | [string]$Group,
79 | [parameter()]
80 | [string]$DomainController = ($env:LOGONSERVER -replace "\\\\")
81 | )
82 | Begin {
83 | #RegEx pattern for output
84 | [regex]$pattern = '^(?\w+)\s+member(?:\s(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+(?:.*\\)?(?\w+|(?:(?:\w{8}-(?:\w{4}-){3}\w{12})))\s+(?:\d+)\s+(?:\d+)\s+(?\d+))?'
85 | }
86 | Process {
87 | If ($Group -notmatch "^CN=.*") {
88 | Write-Verbose "Attempting to get distinguished name of $Group"
89 |
90 | Try {
91 | $distinguishedName = ([adsisearcher]"name=$group").Findone().Properties['distinguishedname'][0]
92 | If (-Not $distinguishedName) {Throw "Fail!"}
93 | } Catch {
94 | Write-Warning "Unable to locate $group"
95 | Break
96 | }
97 |
98 | } Else {$distinguishedName = $Group}
99 |
100 | Write-Verbose "Distinguished Name is $distinguishedName"
101 | $data = (repadmin /showobjmeta $DomainController $distinguishedName | Select-String "^\w+\s+member" -Context 2)
102 |
103 | ForEach ($rep in $data) {
104 | If ($rep.line -match $pattern) {
105 | $object = New-Object PSObject -Property @{
106 | Username = [regex]::Matches($rep.context.postcontext,"CN=(?.*?),.*") | ForEach {$_.Groups['Username'].Value}
107 | LastModified = If ($matches.DateTime) {[datetime]$matches.DateTime} Else {$Null}
108 | DomainController = $matches.dc
109 | Group = $distinguishedName
110 | State = $matches.state
111 | ModifiedCount = $matches.modified
112 | }
113 |
114 | $object.pstypenames.insert(0,'ActiveDirectory.Group.Info')
115 | $object
116 | }
117 | }
118 | }
119 | }
--------------------------------------------------------------------------------
/Get-Certificate.ps1:
--------------------------------------------------------------------------------
1 | Function Get-Certificate {
2 | <#
3 | .SYNOPSIS
4 | Retrieves certificates from a local or remote system.
5 |
6 | .DESCRIPTION
7 | Retrieves certificates from a local or remote system. Also includes the
8 | time until expiration and allows for filtering of certificates and includes
9 | archived certificates.
10 |
11 | .PARAMETER Computername
12 | A single or list of computernames to perform search against
13 |
14 | .PARAMETER StoreName
15 | The name of the certificate store name that you want to search
16 |
17 | .PARAMETER StoreLocation
18 | The location of the certificate store.
19 |
20 | .PARAMETER IncludeArchive
21 | Includes certificates that have been archived
22 |
23 | .PARAMETER Issuer
24 | Filter by certificate Issuer
25 |
26 | .PARAMETER Subject
27 | Filter by certificate Subject
28 |
29 | .PARAMETER Thumbprint
30 | Filter by certificate Thumbprint
31 |
32 | .NOTES
33 | Name: Get-Certificate
34 | Author: Boe Prox
35 | Version History:
36 | 1.3 //Boe Prox
37 | -Added parameters for filtering
38 | -Removed parametersetnames
39 | -Fixed computername output in verbose streams
40 | 1.0 //Boe Prox
41 | -Initial Version
42 |
43 | .EXAMPLE
44 | Get-Certificate -Computername 'boe-pc' -StoreName My -StoreLocation LocalMachine
45 |
46 | Thumbprint Subject
47 | ---------- -------
48 | F29B6CB248E3395B2EB45FCA6EA15005F64F2B4E CN=SomeCert
49 | B93BA840652FB8273CCB1ABD804B2A035AA39877 CN=YetAnotherCert
50 | B1FF5E183E5C4F03559E80B49C2546BBB14CCB18 CN=BOE
51 | 65F5A012F0FE3DF8AC6B5D6E07817F05D2DF5104 CN=SomeOtherCert
52 | 63BD74490E182A341405B033DFE6768E00ECF21B CN=www.example.com
53 |
54 | Description
55 | -----------
56 | Lists all certificates
57 |
58 | .EXAMPLE
59 | Get-Certificate -Computername 'boe-pc' -StoreName My -StoreLocation LocalMachine -Subject '*Boe*'
60 |
61 | Thumbprint Subject
62 | ---------- -------
63 | B1FF5E183E5C4F03559E80B49C2546BBB14CCB18 CN=BOE
64 |
65 | Description
66 | -----------
67 | Lists certificates that contain the subject: boe
68 |
69 | #>
70 | [cmdletbinding()]
71 | Param (
72 | [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
73 | [Alias('PSComputername','__Server','IPAddress')]
74 | [string[]]$Computername = $env:COMPUTERNAME,
75 | [parameter()]
76 | [System.Security.Cryptography.X509Certificates.StoreName]$StoreName = 'My',
77 | [parameter()]
78 | [System.Security.Cryptography.X509Certificates.StoreLocation]$StoreLocation = 'LocalMachine',
79 | [parameter()]
80 | [switch]$IncludeArchive,
81 | [parameter()]
82 | [string]$Issuer,
83 | [parameter()]
84 | [string]$Subject,
85 | [parameter()]
86 | [string]$Thumbprint
87 |
88 | )
89 | Begin {
90 | $WhereList = New-Object System.Collections.ArrayList
91 | If ($PSBoundParameters.ContainsKey('Issuer')) {
92 | [void]$WhereList.Add('$_.Issuer -LIKE $Issuer')
93 | }
94 | If ($PSBoundParameters.ContainsKey('Subject')) {
95 | [void]$WhereList.Add('$_.Subject -LIKE $Subject')
96 | }
97 | If ($PSBoundParameters.ContainsKey('Thumbprint')) {
98 | [void]$WhereList.Add('$_.Thumbprint -LIKE $Thumbprint')
99 | }
100 | If ($WhereList.count -gt 0) {
101 | $Where = [scriptblock]::Create($WhereList -join ' -AND ')
102 | Write-Debug "WhereBlock: $($Where)"
103 | }
104 | }
105 | Process {
106 | ForEach ($Computer in $Computername) {
107 | Try {
108 | Write-Verbose ("Connecting to \\{0}\{1}\{2}" -f $Computer,$StoreLocation,$StoreName)
109 | $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store -ArgumentList "\\$($Computer)\$($StoreName)", $StoreLocation
110 | If ($PSBoundParameters.ContainsKey('IncludeArchive')) {
111 | $Flags = [System.Security.Cryptography.X509Certificates.OpenFlags]'ReadOnly','IncludeArchived'
112 | } Else {
113 | $Flags = [System.Security.Cryptography.X509Certificates.OpenFlags]'ReadOnly'
114 | }
115 | $CertStore.Open($Flags)
116 | If ($WhereList.count -gt 0) {
117 | $Certificates = $CertStore.Certificates | Where $Where
118 | } Else {
119 | $Certificates = $CertStore.Certificates
120 | }
121 | $Certificates | ForEach {
122 | $Days = Switch ((New-TimeSpan -End $_.NotAfter).Days) {
123 | {$_ -gt 0} {$_}
124 | Default {'Expired'}
125 | }
126 | $_ | Add-Member -MemberType NoteProperty -Name ExpiresIn -Value $Days -PassThru |
127 | Add-Member -MemberType NoteProperty -Name Computername -Value $Computer -PassThru
128 | }
129 | } Catch {
130 | Write-Warning "$($Computer): $_"
131 | }
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/Get-ClientWSUSSetting.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-ClientWSUSSetting.ps1
--------------------------------------------------------------------------------
/Get-ExchangeCachedMode.ps1:
--------------------------------------------------------------------------------
1 | Function Get-ExchangeCachedMode {
2 | <#
3 | .SYNOPSIS
4 | Retrieves the CachedMode setting for Outlook 2010 on a workstation.
5 |
6 | .DESCRIPTION
7 | Retrieves the CacheMode setting for Outlook 2010 on a workstation.
8 |
9 | .PARAMETER Computername
10 | Collection of computers to check for the CachedMode setting.
11 |
12 | .PARAMETER Throttle
13 | Used to determine how many asynchronous jobs to run.
14 |
15 | .NOTES
16 | Name: Get-ExchangeCachedMode
17 | Author: Boe Prox
18 |
19 | .EXAMPLE
20 |
21 | Get-ExchangeCachedMode -Computername Computer01
22 |
23 | Computername : Computer01
24 | SID : S-1-5-21-0133314170-616249376-839522115-56832
25 | OutlookProfile : Outlook
26 | CachedMode : Disabled
27 | RegValue : 4,16,0,0
28 | isLoggedOn : True
29 | RegKey : 600aa55f87091746a6c0ff6a2b78af55
30 | RegValueName : 00036601
31 | User : Rivendell\PROXB
32 |
33 | Computername : Computer01
34 | SID : S-1-5-21-0133314170-839522115-616249376-56832
35 | OutlookProfile : proxb
36 | CachedMode : Disabled
37 | RegValue : 4,16,0,0
38 | isLoggedOn : True
39 | RegKey : 5470707acae06d4f9d9dd7dfdf21dab5
40 | RegValueName : 00036601
41 | User : Rivendell\PROXB
42 |
43 | Computername : Computer01
44 | SID : S-1-5-21-634939626-536326981-3066512030-1001
45 | OutlookProfile : Outlook
46 | CachedMode : Disabled
47 | RegValue : 4,16,0,0
48 | isLoggedOn : True
49 | RegKey : 5689237acae06d4f9d9dd7dfdf7r8g9u
50 | RegValueName : 00036601
51 | User : Rivendell\SMITHB
52 |
53 | Description
54 | -----------
55 | Performs a query for the CachedMode setting against a remote system.
56 | #>
57 | [cmdletbinding()]
58 | Param (
59 | [parameter(ValueFromPipeLine=$True,ValueFromPipeLineByPropertyName=$True)]
60 | [string[]]$Computername = $Env:Computername,
61 | [parameter()]
62 | [int]$Throttle = 15
63 | )
64 | Begin {
65 | #Required Functions
66 | Function Get-RunspaceData {
67 | [cmdletbinding()]
68 | param(
69 | [switch]$Wait
70 | )
71 | Do {
72 | $more = $false
73 | Foreach($runspace in $runspaces) {
74 | If ($runspace.Runspace.isCompleted) {
75 | $runspace.powershell.EndInvoke($runspace.Runspace)
76 | $runspace.powershell.dispose()
77 | $runspace.Runspace = $null
78 | $runspace.powershell = $null
79 | $Script:i++
80 | } ElseIf ($runspace.Runspace -ne $null) {
81 | $more = $true
82 | }
83 | }
84 | If ($more -AND $PSBoundParameters['Wait']) {
85 | Start-Sleep -Milliseconds 100
86 | }
87 | #Clean out unused runspace jobs
88 | $temphash = $runspaces.clone()
89 | $temphash | Where {
90 | $_.runspace -eq $Null
91 | } | ForEach {
92 | Write-Verbose ("Removing {0}" -f $_.computer)
93 | $Runspaces.remove($_)
94 | }
95 | } while ($more -AND $PSBoundParameters['Wait'])
96 | } #End Function
97 |
98 | #Main collection to hold all data returned from runspace jobs
99 | $Script:report = @()
100 |
101 | #Define hash table for Get-RunspaceData function
102 | $runspacehash = @{}
103 |
104 | #Define Scriptblock for runspaces
105 | $scriptblock = {
106 | Param ($Computer)
107 | #Function required for SID to Username translation
108 | Function ConvertSID-ToUserName {
109 | [cmdletbinding()]
110 | Param (
111 | [parameter()]
112 | [string[]]$SID
113 | )
114 | Process {
115 | ForEach ($S in $Sid) {
116 | Try {
117 | $s = [system.security.principal.securityidentifier]$s
118 | $user = $s.Translate([System.Security.Principal.NTAccount])
119 | New-Object PSObject -Property @{
120 | Name = $user.value
121 | SID = $s.value
122 | }
123 | } Catch {
124 | Write-Warning ("Unable to translate {0}.`n{1}" -f $UserName,$_.Exception.Message)
125 | }
126 | }
127 | }
128 | } #End Function
129 |
130 | #Get logged on user
131 | Try {
132 | $Username = (Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem -ErrorAction Stop).Username
133 | } Catch {
134 | Write-Warning ("{0}: {1}" -f $Computer,$_.Exception.Message)
135 | $Username = "N\A"
136 | }
137 |
138 | $rootkey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("Users",$computer)
139 |
140 | $SIDs = $rootkey.GetSubKeyNames() | Where {
141 | $_ -match "^S-1-5-\d{2}-\d{10}-\d{9}-\d{9}-\d{5}$"
142 | }
143 |
144 | #Match up the SID to a username
145 | $Hash = @{}
146 | $SIDs | ForEach {
147 | $Hash.$_ = (ConvertSID-ToUserName $_ | Select -Expand Name)
148 | $Hash[$hash.$_] = $_
149 | }
150 |
151 | $SIDs | ForEach {
152 | $SID = $_
153 | Try {
154 | If ($hash.$_ -eq $Username) {
155 | $LoggedOn = $True
156 | } Else {
157 | $LoggedOn = $False
158 | }
159 | $Key = $rootkey.OpenSubKey("$_\Software\Microsoft\Windows NT\CurrentVersion\")
160 | If ($Key.GetSubKeyNames() -Contains "Windows Messaging Subsystem") {
161 | $User = $hash.$_
162 | $Profiles = $Key.OpenSubKey("Windows Messaging SubSystem\Profiles")
163 | Write-Verbose ("Getting list of profiles")
164 | $Profiles.GetSubKeyNames() | ForEach {
165 | $OutlookProfile = $_
166 | $Profile = $Profiles.OpenSubKey(("$_"))
167 | $profile.GetSubKeyNames() | ForEach {
168 | If ($profile.OpenSubKey("$_").GetValueNames() -Contains "00036601") {
169 | Write-Verbose ("Checking value for Cached Mode on profile: {0}" -f $OutlookProfile)
170 | $RegKey = $_
171 | $Key = $profile.OpenSubKey("$_")
172 | $Value = $Key.GetValue("00036601")
173 | If ((($Value[0] -bor 0x80) -eq $Value[0]) -AND (($Value[1] -bor 0x1) -eq $Value[1])) {
174 | $CachedMode = 'Enabled'
175 | } Else {
176 | $CachedMode = 'Disabled'
177 | }
178 | New-Object PSObject -Property @{
179 | User = $User
180 | OutlookProfile = $OutlookProfile
181 | CachedMode = $CachedMode
182 | RegValue = ($Value -Join ",")
183 | RegKey = $RegKey
184 | RegValueName = "00036601"
185 | Computername = $Computer
186 | isLoggedOn = $LoggedOn
187 | SID = $SID
188 | }
189 | } Else {
190 | Write-Warning ("[$($Computer)]$OutlookProfile")
191 | }
192 | }
193 | }
194 | } Else {
195 | Write-Warning "Outlook not installed or missing configuration information"
196 | }
197 | } Catch {
198 | Write-Warning ("{0}: {1}" -f $Computer,$_.Exception.Message)
199 | }
200 | } #End ForEach
201 | } #End Scriptblock
202 |
203 | Write-Verbose ("Creating runspace pool and session states")
204 | $sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
205 | $runspacepool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host)
206 | $runspacepool.Open()
207 |
208 | Write-Verbose ("Creating empty collection to hold runspace jobs")
209 | $Script:runspaces = New-Object System.Collections.ArrayList
210 |
211 | }
212 | Process {
213 |
214 | ForEach ($Computer in $Computername) {
215 | If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {
216 | #Create the powershell instance and supply the scriptblock with the other parameters
217 | $powershell = [powershell]::Create().AddScript($ScriptBlock).AddArgument($computer).AddArgument($wmihash)
218 |
219 | #Add the runspace into the powershell instance
220 | $powershell.RunspacePool = $runspacepool
221 |
222 | #Create a temporary collection for each runspace
223 | $temp = "" | Select-Object PowerShell,Runspace,Computer
224 | $Temp.Computer = $Computer
225 | $temp.PowerShell = $powershell
226 |
227 | #Save the handle output when calling BeginInvoke() that will be used later to end the runspace
228 | $temp.Runspace = $powershell.BeginInvoke()
229 | Write-Verbose ("Adding {0} collection" -f $temp.Computer)
230 | $runspaces.Add($temp) | Out-Null
231 | } Else {
232 | Write-Warning ("{0}: Unavailable" -f $Computer)
233 | }
234 |
235 | Write-Verbose ("Checking status of runspace jobs")
236 | Get-RunspaceData @runspacehash
237 | }
238 | } #End Process
239 | End {
240 | Write-Verbose ("Finish processing the remaining runspace jobs: {0}" -f (@(($runspaces | Where {$_.Runspace -ne $Null}).Count)))
241 | $runspacehash.Wait = $true
242 | Get-RunspaceData @runspacehash
243 |
244 | Write-Verbose ("Closing the runspace pool")
245 | $runspacepool.close()
246 | }
247 | }
--------------------------------------------------------------------------------
/Get-FileHash.ps1:
--------------------------------------------------------------------------------
1 | function Get-FileHash {
2 | <#
3 | .SYNOPSIS
4 | Calculates the hash on a given file based on the seleced hash algorithm.
5 |
6 | .DESCRIPTION
7 | Calculates the hash on a given file based on the seleced hash algorithm. Multiple hashing
8 | algorithms can be used with this command.
9 |
10 | .PARAMETER Path
11 | File or files that will be scanned for hashes.
12 |
13 | .PARAMETER Algorithm
14 | The type of algorithm that will be used to determine the hash of a file or files.
15 | Default hash algorithm used is SHA256. More then 1 algorithm type can be used.
16 |
17 | Available hash algorithms:
18 |
19 | MD5
20 | SHA1
21 | SHA256 (Default)
22 | SHA384
23 | SHA512
24 | RIPEM160
25 |
26 | .NOTES
27 | Name: Get-FileHash
28 | Author: Boe Prox
29 | Created: 18 March 2013
30 | Modified: 28 Jan 2014
31 | 1.1 - Fixed bug with incorrect hash when using multiple algorithms
32 |
33 | .OUTPUTS
34 | System.IO.FileInfo.Hash
35 |
36 | .EXAMPLE
37 | Get-FileHash -Path Test2.txt
38 | Path SHA256
39 | ---- ------
40 | C:\users\prox\desktop\TEST2.txt 5f8c58306e46b23ef45889494e991d6fc9244e5d78bc093f1712b0ce671acc15
41 |
42 | Description
43 | -----------
44 | Displays the SHA256 hash for the text file.
45 |
46 | .EXAMPLE
47 | Get-FileHash -Path .\TEST2.txt -Algorithm MD5,SHA256,RIPEMD160 | Format-List
48 | Path : C:\users\prox\desktop\TEST2.txt
49 | MD5 : cb8e60205f5e8cae268af2b47a8e5a13
50 | SHA256 : 5f8c58306e46b23ef45889494e991d6fc9244e5d78bc093f1712b0ce671acc15
51 | RIPEMD160 : e64d1fa7b058e607319133b2aa4f69352a3fcbc3
52 |
53 | Description
54 | -----------
55 | Displays MD5,SHA256 and RIPEMD160 hashes for the text file.
56 |
57 | .EXAMPLE
58 | Get-ChildItem -Filter *.exe | Get-FileHash -Algorithm MD5
59 | Path MD5
60 | ---- ---
61 | C:\users\prox\desktop\handle.exe 50c128c5b28237b3a01afbdf0e546245
62 | C:\users\prox\desktop\PortQry.exe c6ac67f4076ca431acc575912c194245
63 | C:\users\prox\desktop\procexp.exe b4caa7f3d726120e1b835d52fe358d3f
64 | C:\users\prox\desktop\Procmon.exe 9c85f494132cc6027762d8ddf1dd5a12
65 | C:\users\prox\desktop\PsExec.exe aeee996fd3484f28e5cd85fe26b6bdcd
66 | C:\users\prox\desktop\pskill.exe b5891462c9ca5bddfe63d3bae3c14e0b
67 | C:\users\prox\desktop\Tcpview.exe 485bc6763729511dcfd52ccb008f5c59
68 |
69 | Description
70 | -----------
71 | Uses pipeline input from Get-ChildItem to get MD5 hashes of executables.
72 |
73 | #>
74 | [CmdletBinding()]
75 | Param(
76 | [Parameter(Position=0,Mandatory=$true, ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$True)]
77 | [Alias("PSPath","FullName")]
78 | [string[]]$Path,
79 |
80 | [Parameter(Position=1)]
81 | [ValidateSet("MD5","SHA1","SHA256","SHA384","SHA512","RIPEMD160")]
82 | [string[]]$Algorithm = "SHA256"
83 | )
84 | Process {
85 | ForEach ($item in $Path) {
86 | $item = (Resolve-Path $item).ProviderPath
87 | If (-Not ([uri]$item).IsAbsoluteUri) {
88 | Write-Verbose ("{0} is not a full path, using current directory: {1}" -f $item,$pwd)
89 | $item = (Join-Path $pwd ($item -replace "\.\\",""))
90 | }
91 | If(Test-Path $item -Type Container) {
92 | Write-Warning ("Cannot calculate hash for directory: {0}" -f $item)
93 | Return
94 | }
95 | $object = New-Object PSObject -Property @{
96 | Path = $item
97 | }
98 | #Open the Stream
99 | $stream = ([IO.StreamReader]$item).BaseStream
100 | foreach($Type in $Algorithm) {
101 | [string]$hash = -join ([Security.Cryptography.HashAlgorithm]::Create( $Type ).ComputeHash( $stream ) |
102 | ForEach { "{0:x2}" -f $_ })
103 | $null = $stream.Seek(0,0)
104 | #If multiple algorithms are used, then they will be added to existing object
105 | $object = Add-Member -InputObject $Object -MemberType NoteProperty -Name $Type -Value $Hash -PassThru
106 | }
107 | $object.pstypenames.insert(0,'System.IO.FileInfo.Hash')
108 | #Output an object with the hash, algorithm and path
109 | Write-Output $object
110 |
111 | #Close the stream
112 | $stream.Close()
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/Get-GeoIP.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-GeoIP.ps1
--------------------------------------------------------------------------------
/Get-Icon.ps1:
--------------------------------------------------------------------------------
1 | Function Get-Icon {
2 | <#
3 | .SYNOPSIS
4 | Gets the icon from a file
5 |
6 | .DESCRIPTION
7 | Gets the icon from a file and displays it in a variety formats.
8 |
9 | .PARAMETER Path
10 | The path to a file to get the icon
11 |
12 | .PARAMETER ToBytes
13 | Displays outputs as a byte array
14 |
15 | .PARAMETER ToBitmap
16 | Display the icon as a bitmap object
17 |
18 | .PARAMETER ToBase64
19 | Displays the icon in Base64 encoded format
20 |
21 | .NOTES
22 | Name: Get-Icon
23 | Author: Boe Prox
24 | Version History:
25 | 1.0 //Boe Prox - 11JAN2016
26 | - Initial version
27 |
28 | .OUTPUT
29 | System.Drawing.Icon
30 | System.Drawing.Bitmap
31 | System.String
32 | System.Byte[]
33 |
34 | .EXAMPLE
35 | Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe'
36 |
37 | FullName : C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe
38 | Handle : 164169893
39 | Height : 32
40 | Size : {Width=32, Height=32}
41 | Width : 32
42 |
43 | Description
44 | -----------
45 | Returns the System.Drawing.Icon representation of the icon
46 |
47 | .EXAMPLE
48 | Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe' -ToBitmap
49 |
50 | Tag :
51 | PhysicalDimension : {Width=32, Height=32}
52 | Size : {Width=32, Height=32}
53 | Width : 32
54 | Height : 32
55 | HorizontalResolution : 96
56 | VerticalResolution : 96
57 | Flags : 2
58 | RawFormat : [ImageFormat: b96b3caa-0728-11d3-9d7b-0000f81ef32e]
59 | PixelFormat : Format32bppArgb
60 | Palette : System.Drawing.Imaging.ColorPalette
61 | FrameDimensionsList : {7462dc86-6180-4c7e-8e3f-ee7333a7a483}
62 | PropertyIdList : {}
63 | PropertyItems : {}
64 |
65 | Description
66 | -----------
67 | Returns the System.Drawing.Bitmap representation of the icon
68 |
69 | .EXAMPLE
70 | $FileName = 'C:\Temp\PowerShellIcon.png'
71 | $Format = [System.Drawing.Imaging.ImageFormat]::Png
72 | (Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe' -ToBitmap).Save($FileName,$Format)
73 |
74 | Description
75 | -----------
76 | Saves the icon as a file.
77 |
78 | .EXAMPLE
79 | Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe' -ToBase64
80 |
81 | AAABAAEAICAQHQAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAA
82 | AAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP
83 | //AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
84 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmZmZmZmZmZmZmZgAAAAAAaId3d3d3d4iIiIdgAA
85 | AHdmhmZmZmZmZmZmZoZAAAB2ZnZmZmZmZmZmZmZ3YAAAdmZ3ZmiHZniIiHZmaGAAAHZmd2Zv/4eIiIi
86 | GZmhgAAB2ZmdmZ4/4eIh3ZmZnYAAAd2ZnZmZo//h2ZmZmZ3YAAHZmaGZmZo//h2ZmZmd2AAB3Zmd2Zm
87 | Znj/h2ZmZmhgAAd3dndmZmZuj/+GZmZoYAAHd3dod3dmZuj/9mZmZ2AACHd3aHd3eIiP/4ZmZmd2AAi
88 | Hd2iIiIiI//iId2ZndgAIiIhoiIiIj//4iIiIiIYACIiId4iIiP//iIiIiIiGAAiIiIaIiI//+IiIiI
89 | iIhkAIiIiGiIiP/4iIiIiIiIdgCIiIhoiIj/iIiIiIiIiIYAiIiIeIiIiIiIiIiIiIiGAAiIiIaP///
90 | ////////4hgAAAAAGZmZmZmZmZmZmZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
91 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////gA
92 | AAf4AAAD+AAAAfgAAAHAAAABwAAAAcAAAAHAAAAAwAAAAMAAAADAAAAAwAAAAMAAAABAAAAAQAAAAEA
93 | AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAP4AAAH//////////////////////////w==
94 |
95 | Description
96 | -----------
97 | Returns the Base64 encoded representation of the icon
98 |
99 | .EXAMPLE
100 | Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe' -ToBase64 | Clip
101 |
102 | Description
103 | -----------
104 | Returns the Base64 encoded representation of the icon and saves it to the clipboard.
105 |
106 | .EXAMPLE
107 | (Get-Icon -Path 'C:\windows\system32\WindowsPowerShell\v1.0\PowerShell.exe' -ToBytes) -Join ''
108 |
109 | 0010103232162900002322002200040000320006400010400000128200000000000000000000000
110 | 0128001280001281280128000128012801281280012812812801921921920002550025500025525
111 | 5025500025502550255255002552552550000000000000000000000000000000000000000000000
112 | 0000000000000000000000000000000000006102102102102102102102102102102960000613611
113 | 9119119119119120136136136118000119102134102102102102102102102102102134640011810
114 | 2118102102102102102102102102102119960011810211910210413510212013613611810210496
115 | 0011810211910211125513513613613613410210496001181021031021031432481201361191021
116 | 0210396001191021031021021042552481181021021021031180011810210410210210214325513
117 | 5102102102103118001191021031181021021031432481181021021021340011911910311810210
118 | 2102232255248102102102134001191191181351191181021101432551021021021180013511911
119 | 8135119119136136255248102102102119960136119118136136136136143255136135118102119
120 | 9601361361341361361361362552551361361361361369601361361351201361361432552481361
121 | 3613613613696013613613610413613625525513613613613613613610001361361361041361362
122 | 5524813613613613613613611801361361361041361362551361361361361361361361340136136
123 | 1361201361361361361361361361361361361340813613613414325525525525525525525525524
124 | 8134000061021021021021021021021021021021020000000000000000000000000000000000000
125 | 0000000000000000000000000000000000000000000025525525525525525525525525525525525
126 | 5224003122400152240072240070007000700070003000300030003000300010001000100010000
127 | 0000000000000000000012800025400125525525525525525525525525525525525525525525525
128 | 5255255255255
129 |
130 | Description
131 | -----------
132 | Returns the bytes representation of the icon. -Join was used in this for the sake
133 | of displaying all of the data.
134 |
135 | #>
136 | [cmdletbinding(
137 | DefaultParameterSetName = '__DefaultParameterSetName'
138 | )]
139 | Param (
140 | [parameter(ValueFromPipelineByPropertyName=$True)]
141 | [ValidateNotNullorEmpty()]
142 | [string]$Path,
143 | [parameter(ParameterSetName = 'Bytes')]
144 | [switch]$ToBytes,
145 | [parameter(ParameterSetName = 'Bitmap')]
146 | [switch]$ToBitmap,
147 | [parameter(ParameterSetName = 'Base64')]
148 | [switch]$ToBase64
149 | )
150 | Begin {
151 | If ($PSBoundParameters.ContainsKey('Debug')) {
152 | $DebugPreference = 'Continue'
153 | }
154 | Add-Type -AssemblyName System.Drawing
155 | }
156 | Process {
157 | $Path = Convert-Path -Path $Path
158 | Write-Debug $Path
159 | If (Test-Path -Path $Path) {
160 | $Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($Path)|
161 | Add-Member -MemberType NoteProperty -Name FullName -Value $Path -PassThru
162 | If ($PSBoundParameters.ContainsKey('ToBytes')) {
163 | Write-Verbose "Retrieving bytes"
164 | $MemoryStream = New-Object System.IO.MemoryStream
165 | $Icon.save($MemoryStream)
166 | Write-Debug ($MemoryStream | Out-String)
167 | $MemoryStream.ToArray()
168 | $MemoryStream.Flush()
169 | $MemoryStream.Dispose()
170 | } ElseIf ($PSBoundParameters.ContainsKey('ToBitmap')) {
171 | $Icon.ToBitMap()
172 | } ElseIf ($PSBoundParameters.ContainsKey('ToBase64')) {
173 | $MemoryStream = New-Object System.IO.MemoryStream
174 | $Icon.save($MemoryStream)
175 | Write-Debug ($MemoryStream | Out-String)
176 | $Bytes = $MemoryStream.ToArray()
177 | $MemoryStream.Flush()
178 | $MemoryStream.Dispose()
179 | [convert]::ToBase64String($Bytes)
180 | } Else {
181 | $Icon
182 | }
183 | } Else {
184 | Write-Warning "$Path does not exist!"
185 | Continue
186 | }
187 | }
188 | }
--------------------------------------------------------------------------------
/Get-LocalGroupMembership.ps1:
--------------------------------------------------------------------------------
1 | Function Get-LocalGroupMembership {
2 | <#
3 | .SYNOPSIS
4 | Recursively list all members of a specified Local group.
5 |
6 | .DESCRIPTION
7 | Recursively list all members of a specified Local group. This can be run against a local or
8 | remote system or systems. Recursion is unlimited unless specified by the -Depth parameter.
9 |
10 | Alias: glgm
11 |
12 | .PARAMETER Computername
13 | Local or remote computer/s to perform the query against.
14 |
15 | Default value is the local system.
16 |
17 | .PARAMETER Group
18 | Name of the group to query on a system for all members.
19 |
20 | Default value is 'Administrators'
21 |
22 | .PARAMETER Depth
23 | Limit the recursive depth of a query.
24 |
25 | Default value is 2147483647.
26 |
27 | .PARAMETER Throttle
28 | Number of concurrently running jobs to run at a time
29 |
30 | Default value is 10
31 |
32 | .NOTES
33 | Author: Boe Prox
34 | Created: 8 AUG 2013
35 | Version 1.0 (8 AUG 2013):
36 | -Initial creation
37 |
38 | .EXAMPLE
39 | Get-LocalGroupMembership
40 |
41 | Name ParentGroup isGroup Type Computername Depth
42 | ---- ----------- ------- ---- ------------ -----
43 | Administrator Administrators False Domain DC1 1
44 | boe Administrators False Domain DC1 1
45 | testuser Administrators False Domain DC1 1
46 | bob Administrators False Domain DC1 1
47 | proxb Administrators False Domain DC1 1
48 | Enterprise Admins Administrators True Domain DC1 1
49 | Sysops Admins Enterprise Admins True Domain DC1 2
50 | Domain Admins Enterprise Admins True Domain DC1 2
51 | Administrator Enterprise Admins False Domain DC1 2
52 | Domain Admins Administrators True Domain DC1 1
53 | proxb Domain Admins False Domain DC1 2
54 | Administrator Domain Admins False Domain DC1 2
55 | Sysops Admins Administrators True Domain DC1 1
56 | Org Admins Sysops Admins True Domain DC1 2
57 | Enterprise Admins Sysops Admins True Domain DC1 2
58 |
59 | Description
60 | -----------
61 | Gets all of the members of the 'Administrators' group on the local system.
62 |
63 | .EXAMPLE
64 | Get-LocalGroupMembership -Group 'Administrators' -Depth 1
65 |
66 | Name ParentGroup isGroup Type Computername Depth
67 | ---- ----------- ------- ---- ------------ -----
68 | Administrator Administrators False Domain DC1 1
69 | boe Administrators False Domain DC1 1
70 | testuser Administrators False Domain DC1 1
71 | bob Administrators False Domain DC1 1
72 | proxb Administrators False Domain DC1 1
73 | Enterprise Admins Administrators True Domain DC1 1
74 | Domain Admins Administrators True Domain DC1 1
75 | Sysops Admins Administrators True Domain DC1 1
76 |
77 | Description
78 | -----------
79 | Gets the members of 'Administrators' with only 1 level of recursion.
80 |
81 | #>
82 | [cmdletbinding()]
83 | Param (
84 | [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
85 | [Alias('CN','__Server','Computer','IPAddress')]
86 | [string[]]$Computername = $env:COMPUTERNAME,
87 | [parameter()]
88 | [string]$Group = "Administrators",
89 | [parameter()]
90 | [int]$Depth = ([int]::MaxValue),
91 | [parameter()]
92 | [Alias("MaxJobs")]
93 | [int]$Throttle = 10
94 | )
95 | Begin {
96 | $PSBoundParameters.GetEnumerator() | ForEach {
97 | Write-Verbose $_
98 | }
99 | #region Extra Configurations
100 | Write-Verbose ("Depth: {0}" -f $Depth)
101 | #endregion Extra Configurations
102 | #Define hash table for Get-RunspaceData function
103 | $runspacehash = @{}
104 | #Function to perform runspace job cleanup
105 | Function Get-RunspaceData {
106 | [cmdletbinding()]
107 | param(
108 | [switch]$Wait
109 | )
110 | Do {
111 | $more = $false
112 | Foreach($runspace in $runspaces) {
113 | If ($runspace.Runspace.isCompleted) {
114 | $runspace.powershell.EndInvoke($runspace.Runspace)
115 | $runspace.powershell.dispose()
116 | $runspace.Runspace = $null
117 | $runspace.powershell = $null
118 | } ElseIf ($runspace.Runspace -ne $null) {
119 | $more = $true
120 | }
121 | }
122 | If ($more -AND $PSBoundParameters['Wait']) {
123 | Start-Sleep -Milliseconds 100
124 | }
125 | #Clean out unused runspace jobs
126 | $temphash = $runspaces.clone()
127 | $temphash | Where {
128 | $_.runspace -eq $Null
129 | } | ForEach {
130 | Write-Verbose ("Removing {0}" -f $_.computer)
131 | $Runspaces.remove($_)
132 | }
133 | } while ($more -AND $PSBoundParameters['Wait'])
134 | }
135 |
136 | #region ScriptBlock
137 | $scriptBlock = {
138 | Param ($Computer,$Group,$Depth,$NetBIOSDomain,$ObjNT,$Translate)
139 | $Script:Depth = $Depth
140 | $Script:ObjNT = $ObjNT
141 | $Script:Translate = $Translate
142 | $Script:NetBIOSDomain = $NetBIOSDomain
143 | Function Get-LocalGroupMember {
144 | [cmdletbinding()]
145 | Param (
146 | [parameter()]
147 | [System.DirectoryServices.DirectoryEntry]$LocalGroup
148 | )
149 | # Invoke the Members method and convert to an array of member objects.
150 | #Change3 comment from web page by Craig Dempsey to fixe Powershell 5.0 issue
151 | #$Members= @($LocalGroup.psbase.Invoke("Members"))
152 | $Members= @($LocalGroup.psbase.Invoke("Members")) | foreach{([System.DirectoryServices.DirectoryEntry]$_)}
153 | $Counter++
154 | ForEach ($Member In $Members) {
155 | Try {
156 | #Change3
157 | #$Name = $Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null)
158 | #$Path = $Member.GetType().InvokeMember("ADsPath", 'GetProperty', $Null, $Member, $Null)
159 | $Name = $Member.InvokeGet("Name")
160 | $Path = $Member.InvokeGet("AdsPath")
161 |
162 | # Check if this member is a group.
163 | #Change3
164 | #$isGroup = ($Member.GetType().InvokeMember("Class", 'GetProperty', $Null, $Member, $Null) -eq "group")
165 | $isGroup = ($Member.InvokeGet("Class") -eq "group")
166 |
167 | #region Change1 by Kensel
168 | #Remove the domain from the computername to fix the type comparison when supplied with FQDN
169 | IF ($Computer.Contains('.')){
170 | $Computer = $computer.Substring(0,$computer.IndexOf('.'))
171 | }
172 | #endregion Change1 by Kensel
173 |
174 | If (($Path -like "*/$Computer/*")) {
175 | $Type = 'Local'
176 | } Else {$Type = 'Domain'}
177 | #Change2 by Kensel - Add the Group to the output
178 | New-Object PSObject -Property @{
179 | Computername = $Computer
180 | Name = $Name
181 | Type = $Type
182 | ParentGroup = $LocalGroup.Name[0]
183 | isGroup = $isGroup
184 | Depth = $Counter
185 | Group = $Group
186 | }
187 | If ($isGroup) {
188 | # Check if this group is local or domain.
189 | #$host.ui.WriteVerboseLine("(RS)Checking if Counter: {0} is less than Depth: {1}" -f $Counter, $Depth)
190 | If ($Counter -lt $Depth) {
191 | If ($Type -eq 'Local') {
192 | If ($Groups[$Name] -notcontains 'Local') {
193 | $host.ui.WriteVerboseLine(("{0}: Getting local group members" -f $Name))
194 | $Groups[$Name] += ,'Local'
195 | # Enumerate members of local group.
196 | Get-LocalGroupMember $Member
197 | }
198 | } Else {
199 | If ($Groups[$Name] -notcontains 'Domain') {
200 | $host.ui.WriteVerboseLine(("{0}: Getting domain group members" -f $Name))
201 | $Groups[$Name] += ,'Domain'
202 | # Enumerate members of domain group.
203 | Get-DomainGroupMember $Member $Name $True
204 | }
205 | }
206 | }
207 | }
208 | } Catch {
209 | $host.ui.WriteWarningLine(("GLGM{0}" -f $_.Exception.Message))
210 | }
211 | }
212 | }
213 |
214 | Function Get-DomainGroupMember {
215 | [cmdletbinding()]
216 | Param (
217 | [parameter()]
218 | $DomainGroup,
219 | [parameter()]
220 | [string]$NTName,
221 | [parameter()]
222 | [string]$blnNT
223 | )
224 | Try {
225 | If ($blnNT -eq $True) {
226 | # Convert NetBIOS domain name of group to Distinguished Name.
227 | $objNT.InvokeMember("Set", "InvokeMethod", $Null, $Translate, (3, ("{0}{1}" -f $NetBIOSDomain.Trim(),$NTName)))
228 | $DN = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $Translate, 1)
229 | $ADGroup = [ADSI]"LDAP://$DN"
230 | } Else {
231 | $DN = $DomainGroup.distinguishedName
232 | $ADGroup = $DomainGroup
233 | }
234 | $Counter++
235 | ForEach ($MemberDN In $ADGroup.Member) {
236 | $MemberGroup = [ADSI]("LDAP://{0}" -f ($MemberDN -replace '/','\/'))
237 | #Change2 by Kensel - Add the Group to the output
238 | New-Object PSObject -Property @{
239 | Computername = $Computer
240 | Name = $MemberGroup.name[0]
241 | Type = 'Domain'
242 | ParentGroup = $NTName
243 | isGroup = ($MemberGroup.Class -eq "group")
244 | Depth = $Counter
245 | Group = $Group
246 | }
247 | # Check if this member is a group.
248 | If ($MemberGroup.Class -eq "group") {
249 | If ($Counter -lt $Depth) {
250 | If ($Groups[$MemberGroup.name[0]] -notcontains 'Domain') {
251 | Write-Verbose ("{0}: Getting domain group members" -f $MemberGroup.name[0])
252 | $Groups[$MemberGroup.name[0]] += ,'Domain'
253 | # Enumerate members of domain group.
254 | Get-DomainGroupMember $MemberGroup $MemberGroup.Name[0] $False
255 | }
256 | }
257 | }
258 | }
259 | } Catch {
260 | $host.ui.WriteWarningLine(("GDGM{0}" -f $_.Exception.Message))
261 | }
262 | }
263 | #region Get Local Group Members
264 | $Script:Groups = @{}
265 | $Script:Counter=0
266 | # Bind to the group object with the WinNT provider.
267 | $ADSIGroup = [ADSI]"WinNT://$Computer/$Group,group"
268 | Write-Verbose ("Checking {0} membership for {1}" -f $Group,$Computer)
269 | $Groups[$Group] += ,'Local'
270 | Get-LocalGroupMember -LocalGroup $ADSIGroup
271 | #endregion Get Local Group Members
272 | }
273 | #endregion ScriptBlock
274 | Write-Verbose ("Checking to see if connected to a domain")
275 | Try {
276 | $Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
277 | $Root = $Domain.GetDirectoryEntry()
278 | $Base = ($Root.distinguishedName)
279 |
280 | # Use the NameTranslate object.
281 | $Script:Translate = New-Object -comObject "NameTranslate"
282 | $Script:objNT = $Translate.GetType()
283 |
284 | # Initialize NameTranslate by locating the Global Catalog.
285 | $objNT.InvokeMember("Init", "InvokeMethod", $Null, $Translate, (3, $Null))
286 |
287 | # Retrieve NetBIOS name of the current domain.
288 | $objNT.InvokeMember("Set", "InvokeMethod", $Null, $Translate, (1, "$Base"))
289 | [string]$Script:NetBIOSDomain =$objNT.InvokeMember("Get", "InvokeMethod", $Null, $Translate, 3)
290 | } Catch {Write-Warning ("{0}" -f $_.Exception.Message)}
291 |
292 | #region Runspace Creation
293 | Write-Verbose ("Creating runspace pool and session states")
294 | $sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
295 | $runspacepool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host)
296 | $runspacepool.Open()
297 |
298 | Write-Verbose ("Creating empty collection to hold runspace jobs")
299 | $Script:runspaces = New-Object System.Collections.ArrayList
300 | #endregion Runspace Creation
301 | }
302 |
303 | Process {
304 | ForEach ($Computer in $Computername) {
305 | #Create the powershell instance and supply the scriptblock with the other parameters
306 | $powershell = [powershell]::Create().AddScript($scriptBlock).AddArgument($computer).AddArgument($Group).AddArgument($Depth).AddArgument($NetBIOSDomain).AddArgument($ObjNT).AddArgument($Translate)
307 |
308 | #Add the runspace into the powershell instance
309 | $powershell.RunspacePool = $runspacepool
310 |
311 | #Create a temporary collection for each runspace
312 | $temp = "" | Select-Object PowerShell,Runspace,Computer
313 | $Temp.Computer = $Computer
314 | $temp.PowerShell = $powershell
315 |
316 | #Save the handle output when calling BeginInvoke() that will be used later to end the runspace
317 | $temp.Runspace = $powershell.BeginInvoke()
318 | Write-Verbose ("Adding {0} collection" -f $temp.Computer)
319 | $runspaces.Add($temp) | Out-Null
320 |
321 | Write-Verbose ("Checking status of runspace jobs")
322 | Get-RunspaceData @runspacehash
323 | }
324 | }
325 | End {
326 | Write-Verbose ("Finish processing the remaining runspace jobs: {0}" -f (@(($runspaces | Where {$_.Runspace -ne $Null}).Count)))
327 | $runspacehash.Wait = $true
328 | Get-RunspaceData @runspacehash
329 |
330 | #region Cleanup Runspace
331 | Write-Verbose ("Closing the runspace pool")
332 | $runspacepool.close()
333 | $runspacepool.Dispose()
334 | #endregion Cleanup Runspace
335 | }
336 | }
337 |
338 | Set-Alias -Name glgm -Value Get-LocalGroupMembership
--------------------------------------------------------------------------------
/Get-NetworkInfo.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-NetworkInfo.ps1
--------------------------------------------------------------------------------
/Get-PSSQLInstance.ps1:
--------------------------------------------------------------------------------
1 | Function Get-PSSQLInstance {
2 | <#
3 | .SYNOPSIS
4 | Retrieves SQL server information from a local or remote servers.
5 |
6 | .DESCRIPTION
7 | Retrieves SQL server information from a local or remote servers. Pulls all
8 | instances from a SQL server and detects if in a cluster or not.
9 |
10 | .PARAMETER Computername
11 | Local or remote systems to query for SQL information.
12 |
13 | .NOTES
14 | Name: Get-PSSQLInstance
15 | Author: Boe Prox
16 | Version History:
17 | 1.5 //Boe Prox - 31 May 2016
18 | - Added WMI queries for more information
19 | - Custom object type name
20 | 1.0 //Boe Prox - 07 Sept 2013
21 | - Initial Version
22 |
23 | .EXAMPLE
24 | Get-PSSQLInstance -Computername SQL1
25 |
26 | Computername : SQL1
27 | Instance : MSSQLSERVER
28 | SqlServer : SQLCLU
29 | WMINamespace : ComputerManagement10
30 | Sqlstates : 2061
31 | Version : 10.53.6000.34
32 | Splevel : 3
33 | Clustered : True
34 | Installpath : C:\Program Files\Microsoft SQL
35 | Server\MSSQL10_50.MSSQLSERVER\MSSQL
36 | Datapath : D:\MSSQL10_50.MSSQLSERVER\MSSQL
37 | Language : 1033
38 | Fileversion : 2009.100.6000.34
39 | Vsname : SQLCLU
40 | Regroot : Software\Microsoft\Microsoft SQL
41 | Server\MSSQL10_50.MSSQLSERVER
42 | Sku : 1804890536
43 | Skuname : Enterprise Edition (64-bit)
44 | Instanceid : MSSQL10_50.MSSQLSERVER
45 | Startupparameters : -dD:\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\master.mdf;-eD:\MSSQL1
46 | 0_50.MSSQLSERVER\MSSQL\Log\ERRORLOG;-lD:\MSSQL10_50.MSSQLSERV
47 | ER\MSSQL\DATA\mastlog.ldf
48 | Errorreporting : False
49 | Dumpdir : D:\MSSQL10_50.MSSQLSERVER\MSSQL\LOG\
50 | Sqmreporting : False
51 | Iswow64 : False
52 | BackupDirectory : F:\MSSQL10_50.MSSQLSERVER\MSSQL\Backup
53 | AlwaysOnName :
54 | Nodes : {SQL1, SQL2}
55 | Caption : SQL Server 2008 R2
56 | FullName : SQLCLU\MSSQLSERVER
57 |
58 | Description
59 | -----------
60 | Retrieves the SQL information from SQL1
61 | #>
62 | [OutputType('SQLServer.Information')]
63 | [cmdletbinding()]
64 | Param(
65 | [parameter(ValueFromPipeline=$True)]
66 | [string[]]$Computername = 'G13'
67 | )
68 | Process {
69 | ForEach ($Computer in $Computername) {
70 | # 1 = MSSQLSERVER
71 | $Filter = "SELECT * FROM SqlServiceAdvancedProperty WHERE SqlServiceType=1"
72 | $WMIParams=@{
73 | Computername = $Computer
74 | NameSpace='root\Microsoft\SqlServer'
75 | Query="SELECT name FROM __NAMESPACE WHERE name LIKE 'ComputerManagement%'"
76 | Authentication = 'PacketPrivacy'
77 | ErrorAction = 'Stop'
78 | }
79 | Write-Verbose "[$Computer] Starting SQL Scan"
80 | $PropertyHash = [ordered]@{
81 | Computername = $Computer
82 | Instance = $Null
83 | SqlServer = $Null
84 | WmiNamespace = $Null
85 | SQLSTATES = $Null
86 | VERSION = $Null
87 | SPLEVEL = $Null
88 | CLUSTERED = $Null
89 | INSTALLPATH = $Null
90 | DATAPATH = $Null
91 | LANGUAGE = $Null
92 | FILEVERSION = $Null
93 | VSNAME = $Null
94 | REGROOT = $Null
95 | SKU = $Null
96 | SKUNAME = $Null
97 | INSTANCEID = $Null
98 | STARTUPPARAMETERS = $Null
99 | ERRORREPORTING = $Null
100 | DUMPDIR = $Null
101 | SQMREPORTING = $Null
102 | ISWOW64 = $Null
103 | BackupDirectory = $Null
104 | AlwaysOnName = $Null
105 | }
106 | Try {
107 | Write-Verbose "[$Computer] Performing Registry Query"
108 | $Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
109 | }
110 | Catch {
111 | Write-Warning "[$Computer] $_"
112 | Continue
113 | }
114 | $baseKeys = "SOFTWARE\\Microsoft\\Microsoft SQL Server",
115 | "SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SQL Server"
116 | Try {
117 | $ErrorActionPreference = 'Stop'
118 | If ($Registry.OpenSubKey($basekeys[0])) {
119 | $regPath = $basekeys[0]
120 | }
121 | ElseIf ($Registry.OpenSubKey($basekeys[1])) {
122 | $regPath = $basekeys[1]
123 | }
124 | Else {
125 | Continue
126 | }
127 | }
128 | Catch {
129 | Continue
130 | }
131 | Finally {
132 | $ErrorActionPreference = 'Continue'
133 | }
134 | $RegKey= $Registry.OpenSubKey("$regPath")
135 | If ($RegKey.GetSubKeyNames() -contains "Instance Names") {
136 | $RegKey= $Registry.OpenSubKey("$regpath\\Instance Names\\SQL" )
137 | $instances = @($RegKey.GetValueNames())
138 | }
139 | ElseIf ($regKey.GetValueNames() -contains 'InstalledInstances') {
140 | $isCluster = $False
141 | $instances = $RegKey.GetValue('InstalledInstances')
142 | }
143 | Else {
144 | Continue
145 | }
146 |
147 | If ($instances.count -gt 0) {
148 | ForEach ($Instance in $Instances) {
149 | $PropertyHash['Instance']=$Instance
150 | $Nodes = New-Object System.Collections.Arraylist
151 | $clusterName = $Null
152 | $isCluster = $False
153 | $instanceValue = $regKey.GetValue($instance)
154 | $instanceReg = $Registry.OpenSubKey("$regpath\\$instanceValue")
155 | If ($instanceReg.GetSubKeyNames() -contains "Cluster") {
156 | $isCluster = $True
157 | $instanceRegCluster = $instanceReg.OpenSubKey('Cluster')
158 | $clusterName = $instanceRegCluster.GetValue('ClusterName')
159 | $clusterReg = $Registry.OpenSubKey("Cluster\\Nodes")
160 | $clusterReg.GetSubKeyNames() | ForEach {
161 | $null = $Nodes.Add($clusterReg.OpenSubKey($_).GetValue('NodeName'))
162 | }
163 | }
164 | $PropertyHash['Nodes'] = $Nodes
165 |
166 | $instanceRegSetup = $instanceReg.OpenSubKey("Setup")
167 | Try {
168 | $edition = $instanceRegSetup.GetValue('Edition')
169 | } Catch {
170 | $edition = $Null
171 | }
172 | $PropertyHash['Skuname'] = $edition
173 | Try {
174 | $ErrorActionPreference = 'Stop'
175 | #Get from filename to determine version
176 | $servicesReg = $Registry.OpenSubKey("SYSTEM\\CurrentControlSet\\Services")
177 | $serviceKey = $servicesReg.GetSubKeyNames() | Where {
178 | $_ -eq ('MSSQL${0}' -f $instance)
179 | } | Select -First 1
180 | $service = $servicesReg.OpenSubKey($serviceKey).GetValue('ImagePath')
181 | $file = $service -replace '^.*(\w:\\.*\\sqlservr.exe).*','$1'
182 | $PropertyHash['version'] =(Get-Item ("\\$Computer\$($file -replace ":","$")")).VersionInfo.ProductVersion
183 | } Catch {
184 | #Use potentially less accurate version from registry
185 | $PropertyHash['Version'] = $instanceRegSetup.GetValue('Version')
186 | } Finally {
187 | $ErrorActionPreference = 'Continue'
188 | }
189 |
190 | Try {
191 | Write-Verbose "[$Computer] Performing WMI Query"
192 | $Namespace = $Namespace = (Get-WMIObject @WMIParams | Sort-Object -Descending | Select-Object -First 1).Name
193 | If ($Namespace) {
194 | $PropertyHash['WMINamespace'] = $Namespace
195 | $WMIParams.NameSpace="root\Microsoft\SqlServer\$Namespace"
196 | $WMIParams.Query=$Filter
197 |
198 | $WMIResults = Get-WMIObject @WMIParams
199 | $GroupResults = $WMIResults | Group ServiceName
200 | $PropertyHash['Instance'] = $GroupResults.Name
201 | $WMIResults | ForEach {
202 | $Name = "{0}{1}" -f ($_.PropertyName.SubString(0,1),$_.PropertyName.SubString(1).ToLower())
203 | $Data = If ($_.PropertyStrValue) {
204 | $_.PropertyStrValue
205 | }
206 | Else {
207 | If ($Name -match 'Clustered|ErrorReporting|SqmReporting|IsWow64') {
208 | [bool]$_.PropertyNumValue
209 | }
210 | Else {
211 | $_.PropertyNumValue
212 | }
213 | }
214 | $PropertyHash[$Name] = $Data
215 | }
216 |
217 | #region Always on availability group
218 | if ($PropertyHash['Version'].Major -ge 11) {
219 | $splat.Query="SELECT WindowsFailoverClusterName FROM HADRServiceSettings WHERE InstanceName = '$($Group.Name)'"
220 | $PropertyHash['AlwaysOnName'] = (Get-WmiObject @WMIParams).WindowsFailoverClusterName
221 | if ($PropertyHash['AlwaysOnName']) {
222 | $PropertyHash.SqlServer = $PropertyHash['AlwaysOnName']
223 | }
224 | }
225 | else {
226 | $PropertyHash['AlwaysOnName'] = $null
227 | }
228 | #endregion Always on availability group
229 |
230 | #region Backup Directory
231 | $RegKey=$Registry.OpenSubKey("$($PropertyHash['RegRoot'])\MSSQLServer")
232 | $PropertyHash['BackupDirectory'] = $RegKey.GetValue('BackupDirectory')
233 | #endregion Backup Directory
234 | }#IF NAMESPACE
235 | }
236 | Catch {
237 | }
238 | #region Caption
239 | $Caption = {Switch -Regex ($PropertyHash['version']) {
240 | "^13" {'SQL Server 2016';Break}
241 | "^12" {'SQL Server 2014';Break}
242 | "^11" {'SQL Server 2012';Break}
243 | "^10\.5" {'SQL Server 2008 R2';Break}
244 | "^10" {'SQL Server 2008';Break}
245 | "^9" {'SQL Server 2005';Break}
246 | "^8" {'SQL Server 2000';Break}
247 | Default {'Unknown'}
248 | }}.InvokeReturnAsIs()
249 | $PropertyHash['Caption'] = $Caption
250 | #endregion Caption
251 |
252 | #region Full SQL Name
253 | $Name = If ($clusterName) {
254 | $clusterName
255 | $PropertyHash['SqlServer'] = $clusterName
256 | }
257 | Else {
258 | $Computer
259 | $PropertyHash['SqlServer'] = $Computer
260 | }
261 | $PropertyHash['FullName'] = ("{0}\{1}" -f $Name,$PropertyHash['Instance'])
262 | #emdregion Full SQL Name
263 | $Object = [pscustomobject]$PropertyHash
264 | $Object.pstypenames.insert(0,'SQLServer.Information')
265 | $Object
266 | }#FOREACH INSTANCE
267 | }#IF
268 | }
269 | }
270 | }
271 |
--------------------------------------------------------------------------------
/Get-PendingUpdate.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-PendingUpdate.ps1
--------------------------------------------------------------------------------
/Get-ProductKey.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-ProductKey.ps1
--------------------------------------------------------------------------------
/Get-SCCMClientUpdate.ps1:
--------------------------------------------------------------------------------
1 | Function Get-SCCMClientUpdate {
2 | <#
3 | .SYNOPSIS
4 | Allows you to query for updates via the SCCM Client Agent
5 |
6 | .DESCRIPTION
7 | Allows you to query for updates via the SCCM Client Agent
8 |
9 | .PARAMETER ShowHidden
10 | If in Quiet mode, use ShowHidden to view updates.
11 |
12 | .PARAMETER UpdateAction
13 | Define the type of action to query for.
14 |
15 | The following values are allowed:
16 | Install - This setting retrieves all updates that are available to be installed or in the process of being installed.
17 | Uninstall - This setting retrieves updates that are already installed and are available to be uninstalled.
18 |
19 | .NOTES
20 | Author: Boe Prox
21 | Created: 3July2012
22 | Name: Get-SCCMClientUpdate
23 |
24 | .EXAMPLE
25 | Get-SCCMClientUpdate -ShowHidden | Format-Table Name,KB,BulletinID,EnforcementDeadline,UpdateStatus
26 |
27 | Name KB BulletinID EnforcementDeadline UpdateStatus
28 | ---- -- ---------- ------------------- ------------
29 | Security Update for ... 2709162 {MS12-041} 6/26/2012 1:00:00 AM JobStateWaitInstall
30 | Service Pack 3 for V... 2526301 {} 6/4/2012 8:00:00 PM JobStateDownloading
31 | Security Update for ... 2656374 {MS12-025} 6/26/2012 1:00:00 AM JobStateWaitInstall
32 | Security Update for ... 2656351 {MS11-100} 6/3/2012 11:00:00 PM JobStateStateError
33 | Security Update for ... 2686833 {MS12-038} 6/26/2012 1:00:00 AM JobStateWaitInstall
34 | Cumulative Security ... 2699988 {MS12-037} 6/26/2012 1:00:00 AM JobStateWaitInstall
35 | Security Update for ... 2656368 {MS12-025} 6/26/2012 1:00:00 AM JobStateWaitInstall
36 | Security Update for ... 2686827 {MS12-038} 6/26/2012 1:00:00 AM JobStateWaitInstall
37 | Update for Windows V... 2677070 {} 6/26/2012 1:00:00 AM JobStateWaitInstall
38 | Update for Windows V... 2718704 {} 6/26/2012 1:00:00 AM JobStateWaitInstall
39 | Security Update for ... 2685939 {MS12-036} 6/26/2012 1:00:00 AM JobStateWaitInstall
40 | Windows Malicious So... 890830 {} 6/26/2012 1:00:00 AM JobStateWaitInstall
41 |
42 | Description
43 | -----------
44 | This command will show all updates waiting to be installed on SCCM Client.
45 | #>
46 | [cmdletbinding()]
47 | Param(
48 | [parameter()]
49 | [switch]$ShowHidden,
50 | [parameter()]
51 | [ValidateSet('Install','Uninstall')]
52 | [string]$UpdateAction = 'Install'
53 | )
54 | Begin {
55 | $PSBoundParameters.GetEnumerator() | ForEach {
56 | Write-Verbose ("{0}" -f $_)
57 | }
58 |
59 | $Action = [hashtable]@{
60 | Install = 2
61 | Uninstall = 3
62 | }
63 | $statusHash = [hashtable]@{
64 | 0 = 'JobStateNone'
65 | 1 = 'JobStateAvailable'
66 | 2 = 'JobStateSubmitted'
67 | 3 = 'JobStateDetecting'
68 | 4 = 'JobStateDownloadingCIDef'
69 | 5 = 'JobStateDownloadingSdmPkg'
70 | 6 = 'JobStatePreDownload'
71 | 7 = 'JobStateDownloading'
72 | 8 = 'JobStateWaitInstall'
73 | 9 = 'JobStateInstalling'
74 | 10 = 'JobStatePendingSoftReboot'
75 | 11 = 'JobStatePendingHardReboot'
76 | 12 = 'JobStateWaitReboot'
77 | 13 = 'JobStateVerifying'
78 | 14 = 'JobStateInstallComplete'
79 | 15 = 'JobStateStateError'
80 | 16 = 'JobStateWaitServiceWindo'
81 | }
82 | [ref]$progress = $Null
83 | }
84 | Process {
85 | Write-Verbose ("UpdateAction: {0}" -f $UpdateAction)
86 | Try {
87 | $SCCMUpdate = New-Object -ComObject UDA.CCMUpdatesDeployment
88 | $updates = $SCCMUpdate.EnumerateUpdates(
89 | $Action[$UpdateAction],
90 | $PSBoundParameters['ShowHidden'],
91 | $Progress
92 | )
93 | $Count = $updates.GetCount()
94 | } Catch {
95 | Write-Warning ("{0}" -f $_.Exception.Message)
96 | }
97 | If ($Count -gt 0) {
98 | Write-Verbose ("Found {0} updates!" -f $Count)
99 | Try {
100 | For ($i=0;$i -lt $Count;$i++) {
101 | [ref]$status = $Null
102 | [ref]$Complete = $Null
103 | [ref]$Errors = $Null
104 | $update = $updates.GetUpdate($i)
105 | $UpdateObject = New-Object PSObject -Property @{
106 | KB = $update.GetArticleID()
107 | BulletinID = {Try {$update.GetBulletinID()} Catch {}}.invoke()
108 | DownloadSize = $update.GetDownloadSize()
109 | EnforcementDeadline = $update.GetEnforcementDeadline()
110 | ExclusiveUpdateOption = $update.GetExclusiveUpdateOption()
111 | ID = $update.GetID()
112 | InfoLink = $update.GetInfoLink(1033)
113 | Manufacture = $update.GetManufacturer(1033)
114 | Name = $update.GetName(1033)
115 | NotificationOption = $update.GetNotificationOption()
116 | Progress = $update.GetProgress($status,$Complete,$Errors)
117 | UpdateStatus = $statusHash[$status.value]
118 | ErrorCode = $Errors.Value
119 | RebootDeadling = $update.GetRebootDeadline()
120 | State = $update.GetState()
121 | Summary = $update.GetSummary(1033)
122 | }
123 | $UpdateObject.PSTypeNames.Insert(0,'SCCMUpdate.Update')
124 | $UpdateObject
125 | }
126 | } Catch {
127 | Write-Warning ("{0}" -f $_.Exception.Message)
128 | }
129 | } Else {
130 | Write-Verbose 'No updates found!'
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/Get-ServiceStartModeEvent.ps1:
--------------------------------------------------------------------------------
1 | Function Get-ServiceStartModeEvent {
2 | <#
3 | .SYNOPSIS
4 | Finds all events related to a service startmode change in the event log.
5 |
6 | .DESCRIPTION
7 | Finds all events related to a service startmode change in the event log.
8 |
9 | .PARAMETER Computername
10 | Name of the computer to query
11 |
12 | .PARAMETER Path
13 | The full path to a specified event log that has been archived or saved to
14 | a filesystem location.
15 |
16 | .NOTES
17 | Name: Get-ServiceStartModeEvent
18 | Author: Boe Prox
19 | Version History:
20 | 1.0 //Boe Prox - 07/08/2016
21 | - Initial version
22 |
23 | .EXAMPLE
24 | Get-ServiceStartModeEvent -Computer $Env:Computername
25 |
26 | Description
27 | -----------
28 | Displays all events related to service startmode changes.
29 | #>
30 | [cmdletbinding(
31 | DefaultParameterSetName = 'Computer'
32 | )]
33 | Param (
34 | [parameter(ParameterSetName='Computer')]
35 | [string[]]$Computername = $env:COMPUTERNAME,
36 | [parameter(ParameterSetName='File', ValueFromPipelineByPropertyName = $True)]
37 | [Alias('Fullname')]
38 | [string[]]$Path
39 | )
40 | Begin {
41 | Write-Verbose $PSCmdlet.ParameterSetName
42 | If ($PScmdlet.parametersetname -eq 'File') {
43 | $Query = @"
44 |
45 |
46 |
47 |
48 |
49 | "@
50 | } Else {
51 | $Query = @"
52 |
53 |
54 |
55 |
56 |
57 | "@
58 | }
59 | }
60 | Process {
61 | Switch ($PScmdlet.ParameterSetName) {
62 | 'Computer' {
63 | ForEach ($Computer in $Computername) {
64 | Get-WinEvent -ComputerName $Computer -LogName System -FilterXPath $Query | ForEach {
65 | $Properties = $_.Properties
66 | [pscustomobject] @{
67 | Computername = $_.MachineName
68 | TimeCreated = $_.TimeCreated
69 | Servicename = $Properties[0].Value
70 | PriorStartMode = $Properties[1].Value
71 | CurrentStartMode = $Properties[2].Value
72 | ChangedBy = ([System.Security.Principal.SecurityIdentifier]$_.UserID).Translate([System.Security.Principal.NTAccount]).Value
73 | }
74 | }
75 | }
76 | }
77 | 'File' {
78 | ForEach ($Item in $Path) {
79 | $SearchQuery = $Query -Replace 'TOREPLACE',$Item
80 | Write-Verbose $SearchQuery
81 | Get-WinEvent -Path $Item -FilterXPath $SearchQuery | ForEach {
82 | $Properties = $_.Properties
83 | [pscustomobject] @{
84 | Computername = $_.MachineName
85 | TimeCreated = $_.TimeCreated
86 | Servicename = $Properties[0].Value
87 | PriorStartMode = $Properties[1].Value
88 | CurrentStartMode = $Properties[2].Value
89 | ChangedBy = ([System.Security.Principal.SecurityIdentifier]$_.UserID).Translate([System.Security.Principal.NTAccount]).Value
90 | }
91 | }
92 | }
93 | }
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/Get-ServiceStateEvent.ps1:
--------------------------------------------------------------------------------
1 | Function Get-ServiceStateEvent {
2 | <#
3 | .SYNOPSIS
4 | Finds all events related to a service state change in the event log.
5 |
6 | .DESCRIPTION
7 | Finds all events related to a service state change in the event log.
8 |
9 | .PARAMETER Computername
10 | Name of the computer to query
11 |
12 | .PARAMETER Path
13 | The full path to a specified event log that has been archived or saved to
14 | a filesystem location.
15 |
16 | .NOTES
17 | Name: Get-ServiceStateEvent
18 | Author: Boe Prox
19 | Version History:
20 | 1.0 //Boe Prox - 07/08/2016
21 | - Initial version
22 |
23 | .EXAMPLE
24 | Get-ServiceStateEvent -Computer $Env:Computername
25 |
26 | Description
27 | -----------
28 | Displays all events related to service state changes.
29 | #>
30 | [cmdletbinding(
31 | DefaultParameterSetName = 'Computer'
32 | )]
33 | Param (
34 | [parameter(ParameterSetName='Computer')]
35 | [string[]]$Computername = $env:COMPUTERNAME,
36 | [parameter(ParameterSetName='File', ValueFromPipelineByPropertyName = $True)]
37 | [Alias('Fullname')]
38 | [string[]]$Path
39 | )
40 | Begin {
41 | Write-Verbose $PSCmdlet.ParameterSetName
42 | If ($PScmdlet.parametersetname -eq 'File') {
43 | $Query = @"
44 |
45 |
46 |
47 |
48 |
49 | "@
50 | } Else {
51 | $Query = @"
52 |
53 |
54 |
55 |
56 |
57 | "@
58 | }
59 | }
60 | Process {
61 | Switch ($PScmdlet.ParameterSetName) {
62 | 'Computer' {
63 | ForEach ($Computer in $Computername) {
64 | Get-WinEvent -ComputerName $Computer -LogName System -FilterXPath $Query | ForEach {
65 | $Properties = $_.Properties
66 | [pscustomobject] @{
67 | Computername = $_.MachineName
68 | TimeCreated = $_.TimeCreated
69 | Servicename = $Properties[0].Value
70 | State = $Properties[1].Value
71 | }
72 | }
73 | }
74 | }
75 | 'File' {
76 | ForEach ($Item in $Path) {
77 | $SearchQuery = $Query -Replace 'TOREPLACE',$Item
78 | Write-Verbose $SearchQuery
79 | Get-WinEvent -Path $Item -FilterXPath $SearchQuery | ForEach {
80 | $Properties = $_.Properties
81 | [pscustomobject] @{
82 | Computername = $_.MachineName
83 | TimeCreated = $_.TimeCreated
84 | Servicename = $Properties[0].Value
85 | State = $Properties[1].Value
86 | }
87 | }
88 | }
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/Get-TCPResponse.ps1:
--------------------------------------------------------------------------------
1 | Function Get-TCPResponse {
2 | <#
3 | .SYNOPSIS
4 | Tests TCP port of remote or local system and returns a response header
5 | if applicable
6 |
7 | .DESCRIPTION
8 | Tests TCP port of remote or local system and returns a response header
9 | if applicable
10 |
11 | If server has no default response, then Response property will be NULL
12 |
13 | .PARAMETER Computername
14 | Local or remote system to test connection
15 |
16 | .PARAMETER Port
17 | TCP Port to connect to
18 |
19 | .PARAMETER TCPTimeout
20 | Time until connection should abort
21 |
22 | .NOTES
23 | Name: Get-TCPResponse
24 | Author: Boe Prox
25 | Version History:
26 | 1.0 -- 15 Jan 2014
27 | -Initial build
28 |
29 | .INPUTS
30 | System.String
31 |
32 | .OUTPUTS
33 | Net.TCPResponse
34 |
35 | .EXAMPLE
36 | Get-TCPResponse -Computername Exchange1 -Port 25
37 |
38 | Computername : Exchange1
39 | Port : 25
40 | IsOpen : True
41 | Response : 220 SMTP Server Ready
42 |
43 | Description
44 | -----------
45 | Checks port 25 of an exchange server and displays header response.
46 | #>
47 | [OutputType('Net.TCPResponse')]
48 | [cmdletbinding()]
49 | Param (
50 | [parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
51 | [Alias('__Server','IPAddress','IP')]
52 | [string[]]$Computername = $env:Computername,
53 | [int[]]$Port = 902,
54 | [int]$TCPTimeout = 1000
55 | )
56 | Process {
57 | ForEach ($Computer in $Computername) {
58 | ForEach ($_port in $Port) {
59 | $stringBuilder = New-Object Text.StringBuilder
60 | $tcpClient = New-Object System.Net.Sockets.TCPClient
61 | $connect = $tcpClient.BeginConnect($Computer,$_port,$null,$null)
62 | $wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout,$false)
63 | If (-NOT $wait) {
64 | $object = [pscustomobject] @{
65 | Computername = $Computer
66 | Port = $_Port
67 | IsOpen = $False
68 | Response = $Null
69 | }
70 | } Else {
71 | While ($True) {
72 | #Let buffer
73 | Start-Sleep -Milliseconds 1000
74 | Write-Verbose "Bytes available: $($tcpClient.Available)"
75 | If ([int64]$tcpClient.Available -gt 0) {
76 | $stream = $TcpClient.GetStream()
77 | $bindResponseBuffer = New-Object Byte[] -ArgumentList $tcpClient.Available
78 | [Int]$response = $stream.Read($bindResponseBuffer, 0, $bindResponseBuffer.count)
79 | $Null = $stringBuilder.Append(($bindResponseBuffer | ForEach {[char][int]$_}) -join '')
80 | } Else {
81 | Break
82 | }
83 | }
84 | $object = [pscustomobject] @{
85 | Computername = $Computer
86 | Port = $_Port
87 | IsOpen = $True
88 | Response = $stringBuilder.Tostring()
89 | }
90 | }
91 | $object.pstypenames.insert(0,'Net.TCPResponse')
92 | Write-Output $object
93 | If ($Stream) {
94 | $stream.Close()
95 | $stream.Dispose()
96 | }
97 | $tcpClient.Close()
98 | $tcpClient.Dispose()
99 | }
100 | }
101 | }
102 | }
--------------------------------------------------------------------------------
/Get-USGSWaterData.ps1:
--------------------------------------------------------------------------------
1 | Function Get-USGSWaterData {
2 | <#
3 | .SYNOPSIS
4 | Retrieves the water height of the Papio Creek along Ft Crook station in Bellevue, NE.
5 | Running without parameters shows last 24 hours worth of data.
6 |
7 | .DESCRIPTION
8 | Retrieves the water height of the Papio Creek along Ft Crook station in Bellevue, NE.
9 | Running without parameters shows last 24 hours worth of data.
10 |
11 | .PARAMETER Location
12 | The location to query for water information.
13 |
14 | Default Value is: 06610795 (Ft Crook - Papio Creek; Bellevue, NE)
15 | Find other values at: http://maps.waterdata.usgs.gov/mapper/index.html
16 |
17 | .PARAMETER StartTime
18 | Oldest starting time to look for data
19 |
20 | .PARAMETER EndTime
21 | The latest time to end search for data
22 |
23 | .NOTES
24 | Name: Get-USGSPapioBellevue
25 | Author: Boe Prox
26 | Version History:
27 | 1.0 //Boe Prox - 16 May 2016
28 | - Initial build
29 |
30 | .INPUTS
31 | System.String
32 |
33 | .OUTPUTS
34 | Web.USGS.Data
35 |
36 | .LINK
37 | http://maps.waterdata.usgs.gov/mapper/index.html
38 |
39 | .EXAMPLE
40 | Get-USGSWaterData | Select-Object -Last 1 | Format-List
41 |
42 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
43 | DateTime : 5/18/2016 6:15:00 AM
44 | Height_FT : 10.52
45 | Discharge : 354
46 |
47 | Description
48 | -----------
49 | Retrieves the last 24 hours worth of data and looking at the most recent 10 entries
50 |
51 | .EXAMPLE
52 | Get-USGSWaterData -StartDate '05/10/2015' -EndDate '05/12/2015' | Select-Object -Last 5 | Format-List
53 |
54 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
55 | DateTime : 5/12/2015 10:45:00 PM
56 | Height_FT : 10.83
57 | Discharge : 413
58 |
59 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
60 | DateTime : 5/12/2015 11:00:00 PM
61 | Height_FT : 10.82
62 | Discharge : 411
63 |
64 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
65 | DateTime : 5/12/2015 11:15:00 PM
66 | Height_FT : 10.84
67 | Discharge : 416
68 |
69 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
70 | DateTime : 5/12/2015 11:30:00 PM
71 | Height_FT : 10.83
72 | Discharge : 413
73 |
74 | Location : 06610795-Papillion-Creek-at-Fort-Crook-Nebr
75 | DateTime : 5/12/2015 11:45:00 PM
76 | Height_FT : 10.82
77 | Discharge : 411
78 |
79 | Description
80 | -----------
81 | Retrieves entries from 05/10/2015 to 05/12/2015
82 | #>
83 | [OutputType('Web.USGS.Data')]
84 | [cmdletbinding()]
85 | Param (
86 | [string]$Location = '06610795', #Ft Crook Rd in Bellevue, NE
87 | [datetime]$StartDate = (Get-Date).AddDays(-1),
88 | [datetime]$EndDate = (Get-Date)
89 | )
90 |
91 | If ($PSBoundParameters.ContainsKey('Debug')) {
92 | $DebugPreference = 'Continue'
93 | }
94 | If ($StartDate.Date -eq (Get-Date).Date) {
95 | $StartDate = $StartDate.AddDays(-1)
96 | }
97 |
98 | $__StartDate = $StartDate.ToString('yyyy-MM-dd')
99 | $__EndDate = $EndDate.ToString('yyyy-MM-dd')
100 | $URI = "http://waterdata.usgs.gov/ne/nwis/uv?cb_00065=on&cb_00060=on&format=html&site_no=$($Location)&period=&begin_date=$($__StartDate)&end_date=$($__EndDate)"
101 | $RegEx = [regex]"^(?(?:\d{2}/){2}\d{4}\s\d{2}:\d{2})\s(?[a-zA-Z]{1,})(?\d{1,}\.\d{2})(?:A|P)\s{2}(?(?:\d{1,},)*\d{1,})(?:A|P)"
102 |
103 | Try {
104 | $Data = Invoke-WebRequest -Uri $URI
105 | }
106 | Catch {
107 | Write-Warning $_
108 | BREAK
109 | }
110 |
111 | If ($Data.ParsedHtml.body.innertext -match 'Redirecting') {
112 | Write-Verbose "Requesting data older or longer than 120 days, performing redirection"
113 | $Data = Invoke-WebRequest -Uri $Data.links.href
114 | }
115 |
116 | $Title = ((@($Data.ParsedHtml.getElementsByTagName('Title'))[0].Text -replace '.*USGS(.*)','$1').Trim() -replace ',|\.') -replace ' ','-'
117 | Write-Verbose "[$($Title)]"
118 | @($Data.ParsedHtml.getElementsByTagName('Table'))[3].InnerText -split '\r\n' | ForEach {
119 | If ($_ -match $RegEx) {
120 | $Object = [pscustomobject]@{
121 | Location = $Title
122 | DateTime = [datetime]$Matches.DateTime
123 | Height_FT = [decimal]$Matches.Height
124 | Discharge = [decimal]$Matches.Discharge -replace ','
125 | }
126 | $Object.pstypenames.insert(0,'Web.USGS.Data')
127 | $Object
128 | }
129 | Else {
130 | Write-Debug "[$($_)] No match found!"
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/Get-WebPage.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Get-WebPage.ps1
--------------------------------------------------------------------------------
/Install-WSUSServer.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Install-WSUSServer.ps1
--------------------------------------------------------------------------------
/Invoke-BalloonTip.ps1:
--------------------------------------------------------------------------------
1 | Function Invoke-BalloonTip {
2 | <#
3 | .Synopsis
4 | Display a balloon tip message in the system tray.
5 |
6 | .Description
7 | This function displays a user-defined message as a balloon popup in the system tray. This function
8 | requires Windows Vista or later.
9 |
10 | .Parameter Message
11 | The message text you want to display. Recommended to keep it short and simple.
12 |
13 | .Parameter Title
14 | The title for the message balloon.
15 |
16 | .Parameter MessageType
17 | The type of message. This value determines what type of icon to display. Valid values are
18 |
19 | .Parameter SysTrayIcon
20 | The path to a file that you will use as the system tray icon. Default is the PowerShell ISE icon.
21 |
22 | .Parameter Duration
23 | The number of seconds to display the balloon popup. The default is 1000.
24 |
25 | .Inputs
26 | None
27 |
28 | .Outputs
29 | None
30 |
31 | .Notes
32 | NAME: Invoke-BalloonTip
33 | VERSION: 1.0
34 | AUTHOR: Boe Prox
35 | #>
36 |
37 | [CmdletBinding()]
38 | Param (
39 | [Parameter(Mandatory=$True,HelpMessage="The message text to display. Keep it short and simple.")]
40 | [string]$Message,
41 |
42 | [Parameter(HelpMessage="The message title")]
43 | [string]$Title="Attention $env:username",
44 |
45 | [Parameter(HelpMessage="The message type: Info,Error,Warning,None")]
46 | [System.Windows.Forms.ToolTipIcon]$MessageType="Info",
47 |
48 | [Parameter(HelpMessage="The path to a file to use its icon in the system tray")]
49 | [string]$SysTrayIconPath='C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe',
50 |
51 | [Parameter(HelpMessage="The number of milliseconds to display the message.")]
52 | [int]$Duration=1000
53 | )
54 |
55 | Add-Type -AssemblyName System.Windows.Forms
56 |
57 | If (-NOT $global:balloon) {
58 | $global:balloon = New-Object System.Windows.Forms.NotifyIcon
59 |
60 | #Mouse double click on icon to dispose
61 | [void](Register-ObjectEvent -InputObject $balloon -EventName MouseDoubleClick -SourceIdentifier IconClicked -Action {
62 | #Perform cleanup actions on balloon tip
63 | Write-Verbose 'Disposing of balloon'
64 | $global:balloon.dispose()
65 | Unregister-Event -SourceIdentifier IconClicked
66 | Remove-Job -Name IconClicked
67 | Remove-Variable -Name balloon -Scope Global
68 | })
69 | }
70 |
71 | #Need an icon for the tray
72 | $path = Get-Process -id $pid | Select-Object -ExpandProperty Path
73 |
74 | #Extract the icon from the file
75 | $balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($SysTrayIconPath)
76 |
77 | #Can only use certain TipIcons: [System.Windows.Forms.ToolTipIcon] | Get-Member -Static -Type Property
78 | $balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]$MessageType
79 | $balloon.BalloonTipText = $Message
80 | $balloon.BalloonTipTitle = $Title
81 | $balloon.Visible = $true
82 |
83 | #Display the tip and specify in milliseconds on how long balloon will stay visible
84 | $balloon.ShowBalloonTip($Duration)
85 |
86 | Write-Verbose "Ending function"
87 |
88 | }
--------------------------------------------------------------------------------
/Invoke-WSUSClientFixID.ps1:
--------------------------------------------------------------------------------
1 | Function Invoke-WSUSClientFix {
2 | <#
3 | .SYNOPSIS
4 | Performs a WSUS client reset on local or remote system.
5 |
6 | .DESCRIPTION
7 | Performs a WSUS client reset on local or remote system.
8 |
9 | .PARAMETER Computername
10 | Name of the remote or local system.
11 |
12 | .NOTES
13 | Name: Invoke-WSUSClientFix
14 | Author: Boe Prox
15 | DateCreated: 18JAN2012
16 | DateModified: 28Mar2014
17 |
18 | .EXAMPLE
19 | Invoke-WSUSClientFix -Computername 'Server' -Verbose
20 |
21 | VERBOSE: Server: Testing network connection
22 | VERBOSE: Server: Stopping wuauserv service
23 | VERBOSE: Server: Making remote registry connection to LocalMachine hive
24 | VERBOSE: Server: Connection to WSUS Client registry keys
25 | VERBOSE: Server: Removing Software Distribution folder and subfolders
26 | VERBOSE: Server: Starting wuauserv service
27 | VERBOSE: Server: Sending wuauclt /resetauthorization /detectnow command
28 |
29 | Description
30 | -----------
31 | This command resets the WSUS client information on Server.
32 | #>
33 | [cmdletbinding(
34 | SupportsShouldProcess=$True
35 | )]
36 | Param (
37 | [parameter(ValueFromPipeLine=$True,ValueFromPipeLineByPropertyName=$True)]
38 | [Alias('__Server','Server','CN')]
39 | [string[]]$Computername = $Env:Computername
40 | )
41 | Begin {
42 | $reghive = [microsoft.win32.registryhive]::LocalMachine
43 | }
44 | Process {
45 | ForEach ($Computer in $Computername) {
46 | Write-Verbose ("{0}: Testing network connection" -f $Computer)
47 | If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {
48 | Write-Verbose ("{0}: Stopping wuauserv service" -f $Computer)
49 | $wuauserv = Get-Service -ComputerName $Computer -Name wuauserv
50 | Stop-Service -InputObject $wuauserv
51 |
52 | Write-Verbose ("{0}: Making remote registry connection to {1} hive" -f $Computer, $reghive)
53 | $remotereg = [microsoft.win32.registrykey]::OpenRemoteBaseKey($reghive,$Computer)
54 | Write-Verbose ("{0}: Connection to WSUS Client registry keys" -f $Computer)
55 | $wsusreg1 = $remotereg.OpenSubKey('Software\Microsoft\Windows\CurrentVersion\WindowsUpdate',$True)
56 | $wsusreg2 = $remotereg.OpenSubKey('Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update',$True)
57 |
58 | #Begin deletion of registry values for WSUS Client
59 | If (-Not [string]::IsNullOrEmpty($wsusreg1.GetValue('SusClientId'))) {
60 | If ($PScmdlet.ShouldProcess("SusClientId","Delete Registry Value")) {
61 | $wsusreg1.DeleteValue('SusClientId')
62 | }
63 | }
64 | If (-Not [string]::IsNullOrEmpty($wsusreg1.GetValue('SusClientIdValidation'))) {
65 | If ($PScmdlet.ShouldProcess("SusClientIdValidation","Delete Registry Value")) {
66 | $wsusreg1.DeleteValue('SusClientIdValidation')
67 | }
68 | }
69 | If (-Not [string]::IsNullOrEmpty($wsusreg1.GetValue('PingID'))) {
70 | If ($PScmdlet.ShouldProcess("PingID","Delete Registry Value")) {
71 | $wsusreg1.DeleteValue('PingID')
72 | }
73 | }
74 | If (-Not [string]::IsNullOrEmpty($wsusreg1.GetValue('AccountDomainSid'))) {
75 | If ($PScmdlet.ShouldProcess("AccountDomainSid","Delete Registry Value")) {
76 | $wsusreg1.DeleteValue('AccountDomainSid')
77 | }
78 | }
79 | If (-Not [string]::IsNullOrEmpty($wsusreg2.GetValue('LastWaitTimeout'))) {
80 | If ($PScmdlet.ShouldProcess("LastWaitTimeout","Delete Registry Value")) {
81 | $wsusreg2.DeleteValue('LastWaitTimeout')
82 | }
83 | }
84 | If (-Not [string]::IsNullOrEmpty($wsusreg2.GetValue('DetectionStartTimeout'))) {
85 | If ($PScmdlet.ShouldProcess("DetectionStartTimeout","Delete Registry Value")) {
86 | $wsusreg2.DeleteValue('DetectionStartTimeout')
87 | }
88 | }
89 | If (-Not [string]::IsNullOrEmpty($wsusreg2.GetValue('NextDetectionTime'))) {
90 | If ($PScmdlet.ShouldProcess("NextDetectionTime","Delete Registry Value")) {
91 | $wsusreg2.DeleteValue('NextDetectionTime')
92 | }
93 | }
94 | If (-Not [string]::IsNullOrEmpty($wsusreg2.GetValue('AUState'))) {
95 | If ($PScmdlet.ShouldProcess("AUState","Delete Registry Value")) {
96 | $wsusreg2.DeleteValue('AUState')
97 | }
98 | }
99 |
100 | Write-Verbose ("{0}: Removing Software Distribution folder and subfolders" -f $Computer)
101 | Try {
102 | Remove-Item "\\$Computer\c$\Windows\SoftwareDistribution" -Recurse -Force -Confirm:$False -ErrorAction Stop
103 | } Catch {
104 | Write-Warning ("{0}: {1}" -f $Computer,$_.Exception.Message)
105 | }
106 |
107 | Write-Verbose ("{0}: Starting wuauserv service" -f $Computer)
108 | Start-Service -InputObject $wuauserv
109 |
110 | Write-Verbose ("{0}: Sending wuauclt /resetauthorization /detectnow command" -f $Computer)
111 | Try {
112 | Invoke-WmiMethod -Path Win32_Process -ComputerName $Computer -Name Create `
113 | -ArgumentList "wuauclt /resetauthorization /detectnow" -ErrorAction Stop | Out-Null
114 | } Catch {
115 | Write-Warning ("{0}: {1}" -f $Computer,$_.Exception.Message)
116 | }
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Invoke-WSUSDBMaintenance.ps1:
--------------------------------------------------------------------------------
1 | Function Invoke-WSUSDBMaintenance {
2 | <#
3 | .SYSNOPSIS
4 | Performs maintenance tasks on the SUSDB database using the WSUS API and T-SQL code.
5 |
6 | .DESCRIPTION
7 | Performs maintenance tasks on the SUSDB database using the WSUS API.
8 |
9 | 1. Identifies indexes that are fragmented and defragments them. For certain
10 | tables, a fill-factor is set in order to improve insert performance.
11 | Based on MSDN sample at http://msdn2.microsoft.com/en-us/library/ms188917.aspx
12 | and tailored for SUSDB requirements
13 | 2. Updates potentially out-of-date table statistics.
14 |
15 | .PARAMETER UpdateServer
16 | Update server to connect to
17 |
18 | .PARAMETER Port
19 | Port to connect to the Update Server. Default port is 80.
20 |
21 | .PARAMETER Secure
22 | Use a secure connection
23 |
24 | .NOTES
25 | Name: Invoke-WSUSDBMaintenance
26 | Author: Boe Prox
27 | DateCreated: 03 Jul 2013
28 |
29 | T-SQL Code used from http://gallery.technet.microsoft.com/scriptcenter/6f8cde49-5c52-4abd-9820-f1d270ddea61
30 |
31 | .EXAMPLE
32 | Invoke-WSUSDBMaintenance -UpdateServer DC1 -Port 80 -Verbose
33 |
34 | VERBOSE: Connecting to DC1
35 | VERBOSE: Connecting to SUSDB on DC1
36 | VERBOSE: Performing operation "Database Maintenance" on Target "SUSDB".
37 | VERBOSE: Completed.
38 |
39 | Description
40 | -----------
41 | Performs database maintenance on the database for Update Server DC1 on DC1
42 | #>
43 | [cmdletbinding(
44 | SupportsShouldProcess = $True
45 | )]
46 | Param(
47 | [parameter(Mandatory=$True)]
48 | [ValidateScript({
49 | If (-Not (Get-Module -List -Name UpdateServices)) {
50 | Try {
51 | Add-Type -Path "$Env:ProgramFiles\Update Services\Api\Microsoft.UpdateServices.Administration.dll"
52 | $True
53 | } Catch {
54 | Throw ("Missing the required assemblies to use the WSUS API from {0}" -f "$Env:ProgramFiles\Update Services\Api")
55 | }
56 | } Else {$True}
57 | })]
58 | [string]$UpdateServer,
59 | [parameter()]
60 | [ValidateSet('80','443','8530','8531')]
61 | [int]$Port = 80,
62 | [parameter()]
63 | [switch]$Secure
64 | )
65 | $tSQL = @"
66 | SET NOCOUNT ON;
67 |
68 | -- Rebuild or reorganize indexes based on their fragmentation levels
69 | DECLARE @work_to_do TABLE (
70 | objectid int
71 | , indexid int
72 | , pagedensity float
73 | , fragmentation float
74 | , numrows int
75 | )
76 |
77 | DECLARE @objectid int;
78 | DECLARE @indexid int;
79 | DECLARE @schemaname nvarchar(130);
80 | DECLARE @objectname nvarchar(130);
81 | DECLARE @indexname nvarchar(130);
82 | DECLARE @numrows int
83 | DECLARE @density float;
84 | DECLARE @fragmentation float;
85 | DECLARE @command nvarchar(4000);
86 | DECLARE @fillfactorset bit
87 | DECLARE @numpages int
88 |
89 | -- Select indexes that need to be defragmented based on the following
90 | -- * Page density is low
91 | -- * External fragmentation is high in relation to index size
92 | INSERT @work_to_do
93 | SELECT
94 | f.object_id
95 | , index_id
96 | , avg_page_space_used_in_percent
97 | , avg_fragmentation_in_percent
98 | , record_count
99 | FROM
100 | sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f
101 | WHERE
102 | (f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
103 | or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0)
104 | or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0)
105 |
106 |
107 | SELECT @numpages = sum(ps.used_page_count)
108 | FROM
109 | @work_to_do AS fi
110 | INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
111 | INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
112 |
113 | -- Declare the cursor for the list of indexes to be processed.
114 | DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
115 |
116 | -- Open the cursor.
117 | OPEN curIndexes
118 |
119 | -- Loop through the indexes
120 | WHILE (1=1)
121 | BEGIN
122 | FETCH NEXT FROM curIndexes
123 | INTO @objectid, @indexid, @density, @fragmentation, @numrows;
124 | IF @@FETCH_STATUS < 0 BREAK;
125 |
126 | SELECT
127 | @objectname = QUOTENAME(o.name)
128 | , @schemaname = QUOTENAME(s.name)
129 | FROM
130 | sys.objects AS o
131 | INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id
132 | WHERE
133 | o.object_id = @objectid;
134 |
135 | SELECT
136 | @indexname = QUOTENAME(name)
137 | , @fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END
138 | FROM
139 | sys.indexes
140 | WHERE
141 | object_id = @objectid AND index_id = @indexid;
142 |
143 | IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
144 | SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
145 | ELSE IF @numrows >= 5000 AND @fillfactorset = 0
146 | SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
147 | ELSE
148 | SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
149 | EXEC (@command);
150 | END
151 |
152 | -- Close and deallocate the cursor.
153 | CLOSE curIndexes;
154 | DEALLOCATE curIndexes;
155 |
156 | IF EXISTS (SELECT * FROM @work_to_do)
157 | BEGIN
158 | SELECT @numpages = @numpages - sum(ps.used_page_count)
159 | FROM
160 | @work_to_do AS fi
161 | INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
162 | INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
163 | END
164 |
165 | --Update all statistics
166 | EXEC sp_updatestats
167 | "@
168 | Write-Verbose ("Connecting to {0}" -f $UpdateServer)
169 | Try {
170 | If (Get-Module -List -Name UpdateServices) {
171 | $Wsus = Get-WSUSServer -Name $UpdateServer -PortNumber $Port
172 | } Else {
173 | $Wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($UpdateServer,$Secure,$Port)
174 | }
175 | $db = $wsus.GetDatabaseConfiguration().CreateConnection()
176 | Write-Verbose ("Connecting to {0} on {1}" -f $db.databasename,$db.servername)
177 | $db.Connect()
178 | If ($PSCmdlet.ShouldProcess($db.Databasename,'Database Maintenance')) {
179 | $db.ExecuteCommandNoResult($tSQL,[System.Data.CommandType]::Text)
180 | $db.CloseCommand()
181 | $db.Close()
182 | }
183 | } Catch {
184 | Write-Warning ("{0}" -f $_.Exception.Message)
185 | }
186 | Write-Verbose "Completed"
187 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Boe Prox
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/New-SymLink.ps1:
--------------------------------------------------------------------------------
1 | Function New-SymLink {
2 | <#
3 | .SYNOPSIS
4 | Creates a Symbolic link to a file or directory
5 |
6 | .DESCRIPTION
7 | Creates a Symbolic link to a file or directory as an alternative to mklink.exe
8 |
9 | .PARAMETER Path
10 | Name of the path that you will reference with a symbolic link.
11 |
12 | .PARAMETER SymName
13 | Name of the symbolic link to create. Can be a full path/unc or just the name.
14 | If only a name is given, the symbolic link will be created on the current directory that the
15 | function is being run on.
16 |
17 | .PARAMETER File
18 | Create a file symbolic link
19 |
20 | .PARAMETER Directory
21 | Create a directory symbolic link
22 |
23 | .NOTES
24 | Name: New-SymLink
25 | Author: Boe Prox
26 | Created: 15 Jul 2013
27 |
28 |
29 | .EXAMPLE
30 | New-SymLink -Path "C:\users\admin\downloads" -SymName "C:\users\admin\desktop\downloads" -Directory
31 |
32 | SymLink Target Type
33 | ------- ------ ----
34 | C:\Users\admin\Desktop\Downloads C:\Users\admin\Downloads Directory
35 |
36 | Description
37 | -----------
38 | Creates a symbolic link to downloads folder that resides on C:\users\admin\desktop.
39 |
40 | .EXAMPLE
41 | New-SymLink -Path "C:\users\admin\downloads\document.txt" -SymName "SomeDocument" -File
42 |
43 | SymLink Target Type
44 | ------- ------ ----
45 | C:\users\admin\desktop\SomeDocument C:\users\admin\downloads\document.txt File
46 |
47 | Description
48 | -----------
49 | Creates a symbolic link to document.txt file under the current directory called SomeDocument.
50 | #>
51 | [cmdletbinding(
52 | DefaultParameterSetName = 'Directory',
53 | SupportsShouldProcess=$True
54 | )]
55 | Param (
56 | [parameter(Position=0,ParameterSetName='Directory',ValueFromPipeline=$True,
57 | ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
58 | [parameter(Position=0,ParameterSetName='File',ValueFromPipeline=$True,
59 | ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
60 | [ValidateScript({
61 | If (Test-Path $_) {$True} Else {
62 | Throw "`'$_`' doesn't exist!"
63 | }
64 | })]
65 | [string]$Path,
66 | [parameter(Position=1,ParameterSetName='Directory')]
67 | [parameter(Position=1,ParameterSetName='File')]
68 | [string]$SymName,
69 | [parameter(Position=2,ParameterSetName='File')]
70 | [switch]$File,
71 | [parameter(Position=2,ParameterSetName='Directory')]
72 | [switch]$Directory
73 | )
74 | Begin {
75 | Try {
76 | $null = [mklink.symlink]
77 | } Catch {
78 | Add-Type @"
79 | using System;
80 | using System.Runtime.InteropServices;
81 |
82 | namespace mklink
83 | {
84 | public class symlink
85 | {
86 | [DllImport("kernel32.dll")]
87 | public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
88 | }
89 | }
90 | "@
91 | }
92 | }
93 | Process {
94 | #Assume target Symlink is on current directory if not giving full path or UNC
95 | If ($SymName -notmatch "^(?:[a-z]:\\)|(?:\\\\\w+\\[a-z]\$)") {
96 | $SymName = "{0}\{1}" -f $pwd,$SymName
97 | }
98 | $Flag = @{
99 | File = 0
100 | Directory = 1
101 | }
102 | If ($PScmdlet.ShouldProcess($Path,'Create Symbolic Link')) {
103 | Try {
104 | $return = [mklink.symlink]::CreateSymbolicLink($SymName,$Path,$Flag[$PScmdlet.ParameterSetName])
105 | If ($return) {
106 | $object = New-Object PSObject -Property @{
107 | SymLink = $SymName
108 | Target = $Path
109 | Type = $PScmdlet.ParameterSetName
110 | }
111 | $object.pstypenames.insert(0,'System.File.SymbolicLink')
112 | $object
113 | } Else {
114 | Throw "Unable to create symbolic link!"
115 | }
116 | } Catch {
117 | Write-warning ("{0}: {1}" -f $path,$_.Exception.Message)
118 | }
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/Out-Voice.ps1:
--------------------------------------------------------------------------------
1 | Function Out-Voice {
2 | <#
3 | .SYNOPSIS
4 | Used to allow PowerShell to speak to you or sends data to a WAV file for later listening.
5 |
6 | .DESCRIPTION
7 | Used to allow PowerShell to speak to you or sends data to a WAV file for later listening.
8 |
9 | .PARAMETER InputObject
10 | Data that will be spoken or sent to a WAV file.
11 |
12 | .PARAMETER Rate
13 | Sets the speaking rate
14 |
15 | .PARAMETER Volume
16 | Sets the output volume
17 |
18 | .PARAMETER ToWavFile
19 | Append output to a Waveform audio format file in a specified format
20 |
21 | .NOTES
22 | Name: Out-Voice
23 | Author: Boe Prox
24 | DateCreated: 12/4/2013
25 |
26 | To Do:
27 | -Support for other installed voices
28 |
29 | .EXAMPLE
30 | "This is a test" | Out-Voice
31 |
32 | Description
33 | -----------
34 | Speaks the string that was given to the function in the pipeline.
35 |
36 | .EXAMPLE
37 | "Today's date is $((get-date).toshortdatestring())" | Out-Voice
38 |
39 | Description
40 | -----------
41 | Says todays date
42 |
43 | .EXAMPLE
44 | "Today's date is $((get-date).toshortdatestring())" | Out-Voice -ToWavFile "C:\temp\test.wav"
45 |
46 | Description
47 | -----------
48 | Says todays date
49 |
50 | #>
51 |
52 | [cmdletbinding(
53 | )]
54 | Param (
55 | [parameter(ValueFromPipeline='True')]
56 | [string[]]$InputObject,
57 | [parameter()]
58 | [ValidateRange(-10,10)]
59 | [Int]$Rate,
60 | [parameter()]
61 | [ValidateRange(1,100)]
62 | $Volume,
63 | [parameter()]
64 | [string]$ToWavFile
65 | )
66 | Begin {
67 | $Script:parameter = $PSBoundParameters
68 | Write-Verbose "Listing parameters being used"
69 | $PSBoundParameters.GetEnumerator() | ForEach {
70 | Write-Verbose "$($_)"
71 | }
72 | Write-Verbose "Loading assemblies"
73 | Add-Type -AssemblyName System.speech
74 | Write-Verbose "Creating Speech object"
75 | $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
76 | Write-Verbose "Setting volume"
77 | If ($PSBoundParameters['Volume']) {
78 | $speak.Volume = $PSBoundParameters['Volume']
79 | } Else {
80 | Write-Verbose "No volume given, using default: 100"
81 | $speak.Volume = 100
82 | }
83 | Write-Verbose "Setting speech rate"
84 | If ($PSBoundParameters['Rate']) {
85 | $speak.Rate = $PSBoundParameters['Rate']
86 | } Else {
87 | Write-Verbose "No rate given, using default: -2"
88 | $speak.rate = -2
89 | }
90 | If ($PSBoundParameters['WavFile']) {
91 | Write-Verbose "Saving speech to wavfile: $wavfile"
92 | $speak.SetOutputToWaveFile($wavfile)
93 | }
94 | }
95 | Process {
96 | ForEach ($line in $inputobject) {
97 | Write-Verbose "Speaking: $line"
98 | $Speak.SpeakAsync(($line | Out-String)) | Out-Null
99 | }
100 | }
101 | End {
102 | If ($PSBoundParameters['ToWavFile']) {
103 | Write-Verbose "Performing cleanup"
104 | $speak.dispose()
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PowerShell_Scripts
2 | Miscellaneous scripts for things that I have done; more scripts will arrive as I get time to update this repo.
3 | Feel free to help update these scripts.
4 |
--------------------------------------------------------------------------------
/Remove-LocalProfile.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Remove-LocalProfile.ps1
--------------------------------------------------------------------------------
/Set-ClientWSUSSetting.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Set-ClientWSUSSetting.ps1
--------------------------------------------------------------------------------
/Set-Owner.ps1:
--------------------------------------------------------------------------------
1 | Function Set-Owner {
2 | <#
3 | .SYNOPSIS
4 | Changes owner of a file or folder to another user or group.
5 |
6 | .DESCRIPTION
7 | Changes owner of a file or folder to another user or group.
8 |
9 | .PARAMETER Path
10 | The folder or file that will have the owner changed.
11 |
12 | .PARAMETER Account
13 | Optional parameter to change owner of a file or folder to specified account.
14 |
15 | Default value is 'Builtin\Administrators'
16 |
17 | .PARAMETER Recurse
18 | Recursively set ownership on subfolders and files beneath given folder.
19 |
20 | .NOTES
21 | Name: Set-Owner
22 | Author: Boe Prox
23 | Version History:
24 | 1.0 - Boe Prox
25 | - Initial Version
26 |
27 | .EXAMPLE
28 | Set-Owner -Path C:\temp\test.txt
29 |
30 | Description
31 | -----------
32 | Changes the owner of test.txt to Builtin\Administrators
33 |
34 | .EXAMPLE
35 | Set-Owner -Path C:\temp\test.txt -Account 'Domain\bprox
36 |
37 | Description
38 | -----------
39 | Changes the owner of test.txt to Domain\bprox
40 |
41 | .EXAMPLE
42 | Set-Owner -Path C:\temp -Recurse
43 |
44 | Description
45 | -----------
46 | Changes the owner of all files and folders under C:\Temp to Builtin\Administrators
47 |
48 | .EXAMPLE
49 | Get-ChildItem C:\Temp | Set-Owner -Recurse -Account 'Domain\bprox'
50 |
51 | Description
52 | -----------
53 | Changes the owner of all files and folders under C:\Temp to Domain\bprox
54 | #>
55 | [cmdletbinding(
56 | SupportsShouldProcess = $True
57 | )]
58 | Param (
59 | [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
60 | [Alias('FullName')]
61 | [string[]]$Path,
62 | [parameter()]
63 | [string]$Account = 'Builtin\Administrators',
64 | [parameter()]
65 | [switch]$Recurse
66 | )
67 | Begin {
68 | #Prevent Confirmation on each Write-Debug command when using -Debug
69 | If ($PSBoundParameters['Debug']) {
70 | $DebugPreference = 'Continue'
71 | }
72 | Try {
73 | [void][TokenAdjuster]
74 | } Catch {
75 | $AdjustTokenPrivileges = @"
76 | using System;
77 | using System.Runtime.InteropServices;
78 |
79 | public class TokenAdjuster
80 | {
81 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
82 | internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
83 | ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
84 | [DllImport("kernel32.dll", ExactSpelling = true)]
85 | internal static extern IntPtr GetCurrentProcess();
86 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
87 | internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
88 | phtok);
89 | [DllImport("advapi32.dll", SetLastError = true)]
90 | internal static extern bool LookupPrivilegeValue(string host, string name,
91 | ref long pluid);
92 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
93 | internal struct TokPriv1Luid
94 | {
95 | public int Count;
96 | public long Luid;
97 | public int Attr;
98 | }
99 | internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
100 | internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
101 | internal const int TOKEN_QUERY = 0x00000008;
102 | internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
103 | public static bool AddPrivilege(string privilege)
104 | {
105 | try
106 | {
107 | bool retVal;
108 | TokPriv1Luid tp;
109 | IntPtr hproc = GetCurrentProcess();
110 | IntPtr htok = IntPtr.Zero;
111 | retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
112 | tp.Count = 1;
113 | tp.Luid = 0;
114 | tp.Attr = SE_PRIVILEGE_ENABLED;
115 | retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
116 | retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
117 | return retVal;
118 | }
119 | catch (Exception ex)
120 | {
121 | throw ex;
122 | }
123 | }
124 | public static bool RemovePrivilege(string privilege)
125 | {
126 | try
127 | {
128 | bool retVal;
129 | TokPriv1Luid tp;
130 | IntPtr hproc = GetCurrentProcess();
131 | IntPtr htok = IntPtr.Zero;
132 | retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
133 | tp.Count = 1;
134 | tp.Luid = 0;
135 | tp.Attr = SE_PRIVILEGE_DISABLED;
136 | retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
137 | retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
138 | return retVal;
139 | }
140 | catch (Exception ex)
141 | {
142 | throw ex;
143 | }
144 | }
145 | }
146 | "@
147 | Add-Type $AdjustTokenPrivileges
148 | }
149 |
150 | #Activate necessary admin privileges to make changes without NTFS perms
151 | [void][TokenAdjuster]::AddPrivilege("SeRestorePrivilege") #Necessary to set Owner Permissions
152 | [void][TokenAdjuster]::AddPrivilege("SeBackupPrivilege") #Necessary to bypass Traverse Checking
153 | [void][TokenAdjuster]::AddPrivilege("SeTakeOwnershipPrivilege") #Necessary to override FilePermissions
154 | }
155 | Process {
156 | ForEach ($Item in $Path) {
157 | Write-Verbose "FullName: $Item"
158 | #The ACL objects do not like being used more than once, so re-create them on the Process block
159 | $DirOwner = New-Object System.Security.AccessControl.DirectorySecurity
160 | $DirOwner.SetOwner([System.Security.Principal.NTAccount]$Account)
161 | $FileOwner = New-Object System.Security.AccessControl.FileSecurity
162 | $FileOwner.SetOwner([System.Security.Principal.NTAccount]$Account)
163 | $DirAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity
164 | $FileAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity
165 | $AdminACL = New-Object System.Security.AccessControl.FileSystemAccessRule('Builtin\Administrators','FullControl','ContainerInherit,ObjectInherit','InheritOnly','Allow')
166 | $FileAdminAcl.AddAccessRule($AdminACL)
167 | $DirAdminAcl.AddAccessRule($AdminACL)
168 | Try {
169 | $Item = Get-Item -LiteralPath $Item -Force -ErrorAction Stop
170 | If (-NOT $Item.PSIsContainer) {
171 | If ($PSCmdlet.ShouldProcess($Item, 'Set File Owner')) {
172 | Try {
173 | $Item.SetAccessControl($FileOwner)
174 | } Catch {
175 | Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Directory.FullName)"
176 | $Item.Directory.SetAccessControl($FileAdminAcl)
177 | $Item.SetAccessControl($FileOwner)
178 | }
179 | }
180 | } Else {
181 | If ($PSCmdlet.ShouldProcess($Item, 'Set Directory Owner')) {
182 | Try {
183 | $Item.SetAccessControl($DirOwner)
184 | } Catch {
185 | Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Parent.FullName)"
186 | $Item.Parent.SetAccessControl($DirAdminAcl)
187 | $Item.SetAccessControl($DirOwner)
188 | }
189 | }
190 | If ($Recurse) {
191 | [void]$PSBoundParameters.Remove('Path')
192 | Get-ChildItem $Item -Force | Set-Owner @PSBoundParameters
193 | }
194 | }
195 | } Catch {
196 | Write-Warning "$($Item): $($_.Exception.Message)"
197 | }
198 | }
199 | }
200 | End {
201 | #Remove priviledges that had been granted
202 | [void][TokenAdjuster]::RemovePrivilege("SeRestorePrivilege")
203 | [void][TokenAdjuster]::RemovePrivilege("SeBackupPrivilege")
204 | [void][TokenAdjuster]::RemovePrivilege("SeTakeOwnershipPrivilege")
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/Set-Password.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Set-Password.ps1
--------------------------------------------------------------------------------
/Set-Window.ps1:
--------------------------------------------------------------------------------
1 | Function Set-Window {
2 | <#
3 | .SYNOPSIS
4 | Sets the window size (height,width) and coordinates (x,y) of
5 | a process window.
6 |
7 | .DESCRIPTION
8 | Sets the window size (height,width) and coordinates (x,y) of
9 | a process window.
10 |
11 | .PARAMETER ProcessName
12 | Name of the process to determine the window characteristics
13 |
14 | .PARAMETER X
15 | Set the position of the window in pixels from the top.
16 |
17 | .PARAMETER Y
18 | Set the position of the window in pixels from the left.
19 |
20 | .PARAMETER Width
21 | Set the width of the window.
22 |
23 | .PARAMETER Height
24 | Set the height of the window.
25 |
26 | .PARAMETER Passthru
27 | Display the output object of the window.
28 |
29 | .NOTES
30 | Name: Set-Window
31 | Author: Boe Prox
32 | Version History
33 | 1.0//Boe Prox - 11/24/2015
34 | - Initial build
35 |
36 | .OUTPUT
37 | System.Automation.WindowInfo
38 |
39 | .EXAMPLE
40 | Get-Process powershell | Set-Window -X 2040 -Y 142 -Passthru
41 |
42 | ProcessName Size TopLeft BottomRight
43 | ----------- ---- ------- -----------
44 | powershell 1262,642 2040,142 3302,784
45 |
46 | Description
47 | -----------
48 | Set the coordinates on the window for the process PowerShell.exe
49 |
50 | #>
51 | [OutputType('System.Automation.WindowInfo')]
52 | [cmdletbinding()]
53 | Param (
54 | [parameter(ValueFromPipelineByPropertyName=$True)]
55 | $ProcessName,
56 | [int]$X,
57 | [int]$Y,
58 | [int]$Width,
59 | [int]$Height,
60 | [switch]$Passthru
61 | )
62 | Begin {
63 | Try{
64 | [void][Window]
65 | } Catch {
66 | Add-Type @"
67 | using System;
68 | using System.Runtime.InteropServices;
69 | public class Window {
70 | [DllImport("user32.dll")]
71 | [return: MarshalAs(UnmanagedType.Bool)]
72 | public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
73 |
74 | [DllImport("User32.dll")]
75 | public extern static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
76 | }
77 | public struct RECT
78 | {
79 | public int Left; // x position of upper-left corner
80 | public int Top; // y position of upper-left corner
81 | public int Right; // x position of lower-right corner
82 | public int Bottom; // y position of lower-right corner
83 | }
84 | "@
85 | }
86 | }
87 | Process {
88 | $Rectangle = New-Object RECT
89 | $Handle = (Get-Process -Name $ProcessName).MainWindowHandle
90 | $Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
91 | If (-NOT $PSBoundParameters.ContainsKey('Width')) {
92 | $Width = $Rectangle.Right - $Rectangle.Left
93 | }
94 | If (-NOT $PSBoundParameters.ContainsKey('Height')) {
95 | $Height = $Rectangle.Bottom - $Rectangle.Top
96 | }
97 | If ($Return) {
98 | $Return = [Window]::MoveWindow($Handle, $x, $y, $Width, $Height,$True)
99 | }
100 | If ($PSBoundParameters.ContainsKey('Passthru')) {
101 | $Rectangle = New-Object RECT
102 | $Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
103 | If ($Return) {
104 | $Height = $Rectangle.Bottom - $Rectangle.Top
105 | $Width = $Rectangle.Right - $Rectangle.Left
106 | $Size = New-Object System.Management.Automation.Host.Size -ArgumentList $Width, $Height
107 | $TopLeft = New-Object System.Management.Automation.Host.Coordinates -ArgumentList $Rectangle.Left, $Rectangle.Top
108 | $BottomRight = New-Object System.Management.Automation.Host.Coordinates -ArgumentList $Rectangle.Right, $Rectangle.Bottom
109 | If ($Rectangle.Top -lt 0 -AND $Rectangle.LEft -lt 0) {
110 | Write-Warning "Window is minimized! Coordinates will not be accurate."
111 | }
112 | $Object = [pscustomobject]@{
113 | ProcessName = $ProcessName
114 | Size = $Size
115 | TopLeft = $TopLeft
116 | BottomRight = $BottomRight
117 | }
118 | $Object.PSTypeNames.insert(0,'System.Automation.WindowInfo')
119 | $Object
120 | }
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/Start-CountDownTimer.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Start-CountDownTimer.ps1
--------------------------------------------------------------------------------
/Test-IsAdmin.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/proxb/PowerShell_Scripts/65d0ac81cb2f73b51dba318e6ae721bdea0db204/Test-IsAdmin.ps1
--------------------------------------------------------------------------------
/Test-Port-README.md:
--------------------------------------------------------------------------------
1 | # Test-Port
2 | ## SYNOPSIS
3 | Tests port on computer.
4 |
5 | ## SYNTAX
6 | ```powershell
7 | Test-Port [-computer] [-port] [-TCPtimeout ] [-UDPtimeout ] [-TCP] [-UDP] [-LocalIP ] []
8 | ```
9 |
10 | ## DESCRIPTION
11 | Performing test(s) if port(s) on remote computer(s) is/are open or not. Test is performed by opening the connection using selected protocol TCP/UDP or both.
12 |
13 | ## PARAMETERS
14 | ### -computer <Array>
15 | Name of server to test port state
16 | ```
17 | Required? true
18 | Position? 1
19 | Accept pipeline input? true (ByValue)
20 | Accept wildcard characters? false
21 | ```
22 |
23 | ### -port <Array>
24 | Port to test
25 | ```
26 | Required? true
27 | Position? 2
28 | Accept pipeline input? false
29 | Accept wildcard characters? false
30 | ```
31 |
32 | ### -TCPtimeout <Int32>
33 | Sets a timeout for TCP port query. (In milliseconds, Default is 1000)
34 | ```
35 | Required? false
36 | Position? named
37 | Default value 1000
38 | Accept pipeline input? false
39 | Accept wildcard characters? false
40 | ```
41 |
42 | ### -UDPtimeout <Int32>
43 | Sets a timeout for UDP port query. (In milliseconds, Default is 1000)
44 | ```
45 | Required? false
46 | Position? named
47 | Default value 1000
48 | Accept pipeline input? false
49 | Accept wildcard characters? false
50 | ```
51 |
52 | ### -TCP <SwitchParameter>
53 | Use TCP protocol. If any protocol is not selected than TCP is used.
54 | ```
55 | Required? false
56 | Position? named
57 | Default value False
58 | Accept pipeline input? false
59 | Accept wildcard characters? false
60 | ```
61 |
62 | ### -UDP <SwitchParameter>
63 | Use UDP protocol. If any protocol is not selected than TCP is used.
64 | ```
65 | Required? false
66 | Position? named
67 | Default value False
68 | Accept pipeline input? false
69 | Accept wildcard characters? false
70 | ```
71 |
72 | ### -LocalIP <IPAddress>
73 | Local IP address used to probe. If not specified any - generally based on a route table - will be used.
74 | ```
75 | Required? false
76 | Position? named
77 | Accept pipeline input? false
78 | Accept wildcard characters? false
79 | ```
80 |
81 | ## NOTES
82 | Name: Test-Port.ps1
83 |
84 | Author: Boe Prox
85 |
86 | Updated by: Wojciech Sciesinski, https://www.linkedin.com/in/sciesinskiwojciech
87 |
88 | DateCreated: 18Aug2010
89 |
90 | Version: 20160519a
91 |
92 |
93 |
94 | List of Ports: https://www.iana.org/assignments/port-numbers
95 |
96 |
97 |
98 | To Do:
99 |
100 | - Add capability to run background jobs for each host to shorten the time to scan.
101 |
102 | ## EXAMPLES
103 | ### EXAMPLE 1
104 | ```powershell
105 | PS C:\>Test-Port -computer 'server' -port 80
106 |
107 | Server : server
108 | Port : 3389
109 | TypePort : TCP
110 | Open : True
111 | LocalIP : 0.0.0.0
112 | Notes :
113 |
114 | Checks port 3389 on server 'server' to see if it is listening
115 | ```
116 |
117 | ### EXAMPLE 2
118 | ```powershell
119 | PS C:\>'server' | Test-Port -port 80
120 |
121 | Server : server
122 | Port : 80
123 | TypePort : TCP
124 | Open : True
125 | LocalIP : 0.0.0.0
126 | Notes :
127 |
128 | Checks port 80 on server 'server' to see if it is listening
129 | ```
130 |
131 |
132 | ### EXAMPLE 3
133 | ```powershell
134 | PS C:\>Test-Port -computer @("server1","server2") -port 80
135 |
136 | Server : server1
137 | Port : 80
138 | TypePort : TCP
139 | Open : True
140 | LocalIP : 0.0.0.0
141 | Notes :
142 |
143 | Server : server2
144 | Port : 80
145 | TypePort : TCP
146 | Open : False
147 | LocalIP : 0.0.0.0
148 | Notes : Connection to Port Timed Out
149 |
150 | Checks port 80 on server1 and server2 to see if it is listening.
151 | ```
152 |
153 |
154 | ### EXAMPLE 4
155 | ```powershell
156 | PS C:\>Test-Port -comp dc1 -port 17 -udp -UDPtimeout 10000
157 |
158 | Server : dc1
159 | Port : 17
160 | TypePort : UDP
161 | Open : True
162 | LocalIP : 0.0.0.0
163 | Notes :
164 |
165 | Queries port 17 (qotd) using the UDP protocol and returns whether port is open or not.
166 | ```
167 |
168 | ### EXAMPLE 5
169 | ```powershell
170 | PS C:\>Test-Port -Computer server3 -Port 53 -UDP -LocalIP 192.168.13.2
171 |
172 | Server : server3
173 | Port : 53
174 | TypePort : UDP
175 | Open : True
176 | LocalIP : 192.168.13.2
177 | Notes :
178 |
179 |
180 | Checks port 53 using the UDP protocol on destination computer with the name server3 using as a source interface with IP address 192.168.13.2 assigned
181 | ```
182 |
183 | ### EXAMPLE 6
184 | ```powershell
185 | PS C:\>@("server1","server2") | Test-Port -port 80
186 |
187 | Checks port 80 on server1 and server2 to see if it is listening.
188 | ```
189 |
190 | ### EXAMPLE 7
191 | ```powershell
192 | PS C:\>(Get-Content hosts.txt) | Test-Port -port 80
193 |
194 | Checks port 80 on servers in host file to see if it is listening.
195 | ```
196 |
197 | ### EXAMPLE 8
198 | ```powershell
199 | PS C:\>Test-Port -computer (Get-Content hosts.txt) -port 80
200 |
201 | Checks port 80 on servers in host file to see if it is listening
202 | ```
203 |
204 |
205 | ### EXAMPLE 9
206 | ```powershell
207 | PS C:\>Test-Port -computer (Get-Content hosts.txt) -port @(1..59)
208 |
209 | Checks a range of ports from 1-59 on all servers in the hosts.txt file
210 | ```
211 |
--------------------------------------------------------------------------------
/Test-Port.ps1:
--------------------------------------------------------------------------------
1 | function Test-Port {
2 | <#
3 | .SYNOPSIS
4 | Tests port on computer.
5 |
6 | .DESCRIPTION
7 | Performing test(s) if port(s) on remote computer(s) is/are open or not. Test is performed by opening the connection using selected protocol TCP/UDP or both.
8 |
9 | .PARAMETER computer
10 | Name of server to test port state
11 |
12 | .PARAMETER port
13 | Port to test
14 |
15 | .PARAMETER tcp
16 | Use TCP protocol. If any protocol is not selected than TCP is used.
17 |
18 | .PARAMETER udp
19 | Use UDP protocol. If any protocol is not selected than TCP is used.
20 |
21 | .PARAMETER UDPTimeOut
22 | Sets a timeout for UDP port query. (In milliseconds, Default is 1000)
23 |
24 | .PARAMETER TCPTimeOut
25 | Sets a timeout for TCP port query. (In milliseconds, Default is 1000)
26 |
27 | .PARAMETER LocalIP
28 | Local IP address used to probe. If not specified any - generally based on a route table - will be used.
29 |
30 | .NOTES
31 | Name: Test-Port.ps1
32 | Author: Boe Prox
33 | Updated by: Wojciech Sciesinski, https://www.linkedin.com/in/sciesinskiwojciech
34 | DateCreated: 18Aug2010
35 | Version: 20160519a
36 |
37 | List of Ports: https://www.iana.org/assignments/port-numbers
38 |
39 | To Do:
40 | Add capability to run background jobs for each host to shorten the time to scan.
41 | .LINK
42 | https://boeprox.wordpress.org
43 |
44 | .LINK
45 | https://github.com/proxb/PowerShell_Scripts
46 |
47 | .EXAMPLE
48 | Test-Port -computer 'server' -port 80
49 |
50 | Server : server
51 | Port : 3389
52 | TypePort : TCP
53 | Open : True
54 | LocalIP : 0.0.0.0
55 | Notes :
56 |
57 | Checks port 3389 on server 'server' to see if it is listening
58 |
59 | .EXAMPLE
60 | 'server' | Test-Port -port 80
61 |
62 | Server : server
63 | Port : 80
64 | TypePort : TCP
65 | Open : True
66 | LocalIP : 0.0.0.0
67 | Notes :
68 |
69 | Checks port 80 on server 'server' to see if it is listening
70 |
71 | .EXAMPLE
72 | Test-Port -computer @("server1","server2") -port 80
73 |
74 | Server : server1
75 | Port : 80
76 | TypePort : TCP
77 | Open : True
78 | LocalIP : 0.0.0.0
79 | Notes :
80 |
81 | Server : server2
82 | Port : 80
83 | TypePort : TCP
84 | Open : False
85 | LocalIP : 0.0.0.0
86 | Notes : Connection to Port Timed Out
87 |
88 | Checks port 80 on server1 and server2 to see if it is listening.
89 |
90 | .EXAMPLE
91 | Test-Port -comp dc1 -port 17 -udp -UDPtimeout 10000
92 |
93 | Server : dc1
94 | Port : 17
95 | TypePort : UDP
96 | Open : True
97 | LocalIP : 0.0.0.0
98 | Notes :
99 |
100 | Queries port 17 (qotd) using the UDP protocol and returns whether port is open or not.
101 |
102 | .EXAMPLE
103 | Test-Port -Computer server3 -Port 53 -UDP -LocalIP 192.168.13.2
104 |
105 | Server : server3
106 | Port : 53
107 | TypePort : UDP
108 | Open : True
109 | LocalIP : 192.168.13.2
110 | Notes :
111 |
112 | Checks port 53 using the UDP protocol on destination computer with the name server3 using as a source interface with IP address 192.168.13.2 assigned
113 |
114 | .EXAMPLE
115 | @("server1","server2") | Test-Port -port 80
116 |
117 | Checks port 80 on server1 and server2 to see if it is listening.
118 |
119 | .EXAMPLE
120 | (Get-Content hosts.txt) | Test-Port -port 80
121 |
122 | Checks port 80 on servers in host file to see if it is listening.
123 |
124 | .EXAMPLE
125 | Test-Port -computer (Get-Content hosts.txt) -port 80
126 |
127 | Checks port 80 on servers in host file to see if it is listening
128 |
129 | .EXAMPLE
130 | Test-Port -computer (Get-Content hosts.txt) -port @(1..59)
131 |
132 | Checks a range of ports from 1-59 on all servers in the hosts.txt file
133 |
134 |
135 |
136 | #>
137 | [cmdletbinding(
138 | DefaultParameterSetName = '',
139 | ConfirmImpact = 'low'
140 | )]
141 | Param (
142 | [Parameter(
143 | Mandatory = $True,
144 | Position = 0,
145 | ParameterSetName = '',
146 | ValueFromPipeline = $True)]
147 | [array]$computer,
148 | [Parameter(
149 | Position = 1,
150 | Mandatory = $True,
151 | ParameterSetName = '')]
152 | [ValidateRange(0, 65535)]
153 | [array]$port,
154 | [Parameter(
155 | Mandatory = $False,
156 | ParameterSetName = '')]
157 | [int]$TCPtimeout = 1000,
158 | [Parameter(
159 | Mandatory = $False,
160 | ParameterSetName = '')]
161 | [int]$UDPtimeout = 1000,
162 | [Parameter(
163 | Mandatory = $False,
164 | ParameterSetName = '')]
165 | [switch]$TCP,
166 | [Parameter(
167 | Mandatory = $False,
168 | ParameterSetName = '')]
169 | [switch]$UDP,
170 | [Parameter(
171 | Mandatory = $False,
172 | ParameterSetName = '')]
173 | [ipaddress]$LocalIP
174 | )
175 | Begin {
176 | If (!$tcp -AND !$udp) { $tcp = $True }
177 | #Typically you never do this, but in this case I felt it was for the benefit of the function
178 | #as any errors will be noted in the output of the report
179 | #$ErrorActionPreference = "SilentlyContinue"
180 | $report = New-Object System.Collections.ArrayList
181 | }
182 | Process {
183 | ForEach ($c in $computer) {
184 | ForEach ($p in $port) {
185 | If ($tcp) {
186 | #Create temporary holder
187 | $temp = "" | Select-Object -Property Server, Port, TypePort, Open, LocalIP, Notes
188 |
189 | #If LocalIP value is provided create IPEndPoint object
190 | # and use it in the constructor Socket constractor
191 |
192 | If ($LocalIP) {
193 | #Create object for connecting to port on computer, provided local IP is used as source
194 | $EndPoint = New-Object System.Net.IPEndPoint ($LocalIP, 0)
195 | Try {
196 | $tcpobject = new-Object Net.Sockets.TcpClient $EndPoint -ErrorAction Continue
197 | }
198 | Catch {
199 | [String]$MessageText = "Network address {0} is not available on the local computer." -f $LocalIP
200 | Throw $MessageText
201 | }
202 | $tempLocalIP = $LocalIP
203 |
204 | #If LocalIP value is not provide use any local IP
205 | }
206 | Else {
207 | #Create object for connecting to port on computer
208 | $tcpobject = new-Object system.Net.Sockets.TcpClient
209 | [ipaddress]$tempLocalIP = "0.0.0.0"
210 | }
211 |
212 | #Connect to remote machine's port
213 | $connect = $tcpobject.BeginConnect($c, $p, $null, $null)
214 |
215 | $connec.s
216 |
217 | #Configure a timeout before quitting
218 | $wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout, $false)
219 | #If timeout
220 | If (!$wait) {
221 | #Close connection
222 | $tcpobject.Close()
223 | Write-Verbose "Connection Timeout"
224 | #Build report
225 | $temp.Server = $c
226 | $temp.Port = $p
227 | $temp.TypePort = "TCP"
228 | $temp.Open = $False
229 | $temp.LocalIP = $tempLocalIP
230 | $temp.Notes = "Connection to Port Timed Out"
231 | }
232 | Else {
233 | $error.Clear()
234 | $tcpobject.EndConnect($connect) | out-Null
235 | #If error
236 | If ($error[0]) {
237 | #Begin making error more readable in report
238 | [string]$string = ($error[0].exception).message
239 | $message = (($string.split(":")[1]).replace('"', "")).TrimStart()
240 | $failed = $true
241 | }
242 | #Close connection
243 | $tcpobject.Close()
244 | #If unable to query port to due failure
245 | If ($failed) {
246 | #Build report
247 | $temp.Server = $c
248 | $temp.Port = $p
249 | $temp.TypePort = "TCP"
250 | $temp.Open = $False
251 | $temp.LocalIP = $tempLocalIP
252 | $temp.Notes = "$message"
253 | }
254 | Else {
255 | #Build report
256 | $temp.Server = $c
257 | $temp.Port = $p
258 | $temp.TypePort = "TCP"
259 | $temp.Open = $True
260 | $temp.LocalIP = $tempLocalIP
261 | $temp.Notes = ""
262 | }
263 | }
264 | #Reset failed value
265 | $failed = $Null
266 | #Merge temp array with report
267 | $report.add($temp) | Out-Null
268 | }
269 | If ($udp) {
270 | #Create temporary holder
271 | $temp = "" | Select-Object -Property Server, Port, TypePort, Open, LocalIP, Notes
272 |
273 | #If LocalIP value is provided create IPEndPoint object
274 | # and use it in the constructor Socket constractor
275 | If ($LocalIP) {
276 | #Create object for connecting to port on computer, provided local IP is used as source
277 | $EndPoint = New-Object System.Net.IPEndPoint ($LocalIP, 0)
278 | Try {
279 | $udpobject = new-Object Net.Sockets.Udpclient $EndPoint -ErrorAction Continue
280 | }
281 | Catch {
282 | [String]$MessageText = "Network address {0} is not available on the local computer." -f $LocalIP
283 | Throw $MessageText
284 | }
285 |
286 | $tempLocalIP = $LocalIP
287 | #If LocalIP value is not provide use any local IP
288 | }
289 | Else {
290 | #Create object for connecting to port on computer, any local IP is used
291 | $udpobject = new-Object system.Net.Sockets.Udpclient
292 | [ipaddress]$tempLocalIP = "0.0.0.0"
293 | }
294 |
295 | #Set a timeout on receiving message
296 | $udpobject.client.ReceiveTimeout = $UDPTimeout
297 |
298 | #Connect to remote machine's port
299 | Write-Verbose "Making UDP connection to remote server"
300 | $udpobject.Connect("$c", $p)
301 | #Sends a message to the host to which you have connected.
302 | Write-Verbose "Sending message to remote host"
303 | $a = new-object system.text.asciiencoding
304 | $byte = $a.GetBytes("$(Get-Date)")
305 | [void]$udpobject.Send($byte, $byte.length)
306 | #IPEndPoint object will allow us to read datagrams sent from any source.
307 | Write-Verbose "Creating remote endpoint"
308 | $remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any, 0)
309 | Try {
310 | #Blocks until a message returns on this socket from a remote host.
311 | Write-Verbose "Waiting for message return"
312 | $receivebytes = $udpobject.Receive([ref]$remoteendpoint)
313 | [string]$returndata = $a.GetString($receivebytes)
314 | If ($returndata) {
315 | Write-Verbose "Connection Successful"
316 | #Build report
317 | $temp.Server = $c
318 | $temp.Port = $p
319 | $temp.TypePort = "UDP"
320 | $temp.Open = $True
321 | $temp.LocalIP = $tempLocalIP
322 | $temp.Notes = $returndata
323 | $udpobject.close()
324 | }
325 | }
326 | Catch {
327 | If ($Error[0].ToString() -match "\bRespond after a period of time\b") {
328 | #Close connection
329 | $udpobject.Close()
330 | #Make sure that the host is online and not a false positive that it is open
331 | If (Test-Connection -comp $c -count 1 -quiet) {
332 | Write-Verbose "Connection Open"
333 | #Build report
334 | $temp.Server = $c
335 | $temp.Port = $p
336 | $temp.TypePort = "UDP"
337 | $temp.Open = $True
338 | $temp.LocalIP = $tempLocalIP
339 | $temp.Notes = ""
340 | }
341 | Else {
342 | <#
343 | It is possible that the host is not online or that the host is online,
344 | but ICMP is blocked by a firewall and this port is actually open.
345 | #>
346 | Write-Verbose "Host maybe unavailable"
347 | #Build report
348 | $temp.Server = $c
349 | $temp.Port = $p
350 | $temp.TypePort = "UDP"
351 | $temp.Open = $False
352 | $temp.LocalIP = $tempLocalIP
353 | $temp.Notes = "Unable to verify if port is open or if host is unavailable."
354 | }
355 | }
356 | ElseIf ($Error[0].ToString() -match "forcibly closed by the remote host") {
357 | #Close connection
358 | $udpobject.Close()
359 | Write-Verbose "Connection Timeout"
360 | #Build report
361 | $temp.Server = $c
362 | $temp.Port = $p
363 | $temp.TypePort = "UDP"
364 | $temp.Open = $False
365 | $temp.LocalIP = $tempLocalIP
366 | $temp.Notes = "Connection to Port Timed Out"
367 | }
368 | Else {
369 | $udpobject.close()
370 | }
371 | }
372 | #Merge temp array with report
373 | $report.add($temp) | out-null
374 | }
375 | }
376 | }
377 | }
378 | End {
379 | #Generate Report
380 | Return $report
381 | }
382 | }
383 |
--------------------------------------------------------------------------------