new push
This commit is contained in:
76
Asteroid.ps1
Normal file
76
Asteroid.ps1
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
Function Start-AdfsServerTrace {
|
||||||
|
param (
|
||||||
|
[string]$ActivityId,
|
||||||
|
[switch]$IncludeDebug,
|
||||||
|
[string[]]$ComputerName
|
||||||
|
)
|
||||||
|
|
||||||
|
$jobs = @()
|
||||||
|
foreach ($computer in $ComputerName) {
|
||||||
|
$jobs += Start-Job -ScriptBlock {
|
||||||
|
param ($ActivityId, $IncludeDebug, $computer)
|
||||||
|
|
||||||
|
$logNames = @("Security", "Application", "System")
|
||||||
|
if ($IncludeDebug) { $logNames += "AD FS Tracing/Debug" }
|
||||||
|
|
||||||
|
$events = @()
|
||||||
|
foreach ($log in $logNames) {
|
||||||
|
try {
|
||||||
|
$events += Get-WinEvent -ComputerName $computer -LogName $log -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.ActivityId -eq $ActivityId }
|
||||||
|
} catch {
|
||||||
|
Write-Error "Failed to retrieve events from $computer for log $log"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
ComputerName = $computer
|
||||||
|
Events = $events
|
||||||
|
}
|
||||||
|
} -ArgumentList $ActivityId, $IncludeDebug, $computer
|
||||||
|
}
|
||||||
|
|
||||||
|
return $jobs
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Receive-AdfsServerTrace {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[System.Management.Automation.Job[]]$Jobs
|
||||||
|
)
|
||||||
|
|
||||||
|
$results = @()
|
||||||
|
foreach ($job in $Jobs) {
|
||||||
|
$jobResult = Receive-Job -Job $job -Wait -AutoRemoveJob
|
||||||
|
$results += $jobResult
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-AdfsServerTrace {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$ActivityId,
|
||||||
|
|
||||||
|
[switch]$IncludeDebug,
|
||||||
|
|
||||||
|
[string]$OutHtmlFilePath,
|
||||||
|
|
||||||
|
[string[]]$ComputerName = @("localhost")
|
||||||
|
)
|
||||||
|
|
||||||
|
# Start jobs to search all computers in parallel and retrieve results
|
||||||
|
$jobs = Start-AdfsServerTrace -ActivityId $ActivityId -IncludeDebug:$IncludeDebug -ComputerName $ComputerName
|
||||||
|
$results = Receive-AdfsServerTrace -Jobs $jobs
|
||||||
|
|
||||||
|
if ($OutHtmlFilePath) {
|
||||||
|
$results | ConvertTo-Html -Property ComputerName, Events | Out-File $OutHtmlFilePath -Force
|
||||||
|
Write-Output "Report Generated at $OutHtmlFilePath"
|
||||||
|
Start-Process $OutHtmlFilePath
|
||||||
|
} else {
|
||||||
|
Write-Output $results
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Binoculars.ps1
Normal file
51
Binoculars.ps1
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
## Created by Zak Bearman - Intel - Datacom - For use on any domain that WinRM is enabled and supported for remote log searching##
|
||||||
|
cls
|
||||||
|
# Define the username you are searching for
|
||||||
|
$username = read-host "Please enter users account" # Replace with the username of the locked-out user
|
||||||
|
# Get the PDC Emulator
|
||||||
|
$pdcemulator = (Get-ADDomain).PDCEmulator
|
||||||
|
$DomainControllers = Get-ADDomainController $pdcemulator | Select-Object -ExpandProperty HostName
|
||||||
|
|
||||||
|
# Define log file path
|
||||||
|
$logFile = "C:\Temp\AccountLockoutLog.txt"
|
||||||
|
|
||||||
|
# Create the log file if it doesn't exist
|
||||||
|
if (-not (Test-Path $logFile)) {
|
||||||
|
New-Item -Path $logFile -ItemType File -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
# Loop indefinitely every 5 minutes
|
||||||
|
while ($true) {
|
||||||
|
foreach ($DC in $DomainControllers) {
|
||||||
|
Write-Host "Searching on: $DC"
|
||||||
|
Add-Content -Path $logFile -Value "Searching on: $DC - $(Get-Date)"
|
||||||
|
|
||||||
|
# Use Invoke-Command to remotely query the domain controller
|
||||||
|
Invoke-Command -ComputerName $DC -ScriptBlock {
|
||||||
|
param ($username)
|
||||||
|
|
||||||
|
# Query the Security event log for Event ID 4625 (Failed Login Attempt)
|
||||||
|
$events4625 = Get-EventLog -LogName "Security" -InstanceId 4625 -Newest 1000 | Where-Object { $_.Message -like "*$username*" }
|
||||||
|
foreach ($event in $events4625) {
|
||||||
|
$timeGenerated = $event.TimeGenerated
|
||||||
|
$message = $event.Message
|
||||||
|
|
||||||
|
Write-Host "Failed login attempt: $message at $timeGenerated"
|
||||||
|
Add-Content -Path $using:logFile -Value "Failed login attempt: $message at $timeGenerated"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query the Security event log for Event ID 4740 (Account Lockout)
|
||||||
|
$events4740 = Get-EventLog -LogName "Security" -InstanceId 4740 -Newest 1000 | Where-Object { $_.Message -like "*$username*" }
|
||||||
|
foreach ($event in $events4740) {
|
||||||
|
$timeGenerated = $event.TimeGenerated
|
||||||
|
$message = $event.Message
|
||||||
|
|
||||||
|
Write-Host "Account locked out: $message at $timeGenerated"
|
||||||
|
Add-Content -Path $using:logFile -Value "Account locked out: $message at $timeGenerated"
|
||||||
|
}
|
||||||
|
} -ArgumentList $username
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for 10 seconds (10 seconds)
|
||||||
|
Start-Sleep -Seconds 10
|
||||||
|
}
|
||||||
317
Cartographer.ps1
Normal file
317
Cartographer.ps1
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
# Cartographer - DNS Record Mapping Tool with GUI - Map - IP to DNS record based on subnet
|
||||||
|
# Import required assemblies for GUI
|
||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
|
||||||
|
# Convert IP addresses to integers for comparison
|
||||||
|
function Convert-IPToInt {
|
||||||
|
param (
|
||||||
|
[string]$IPAddress
|
||||||
|
)
|
||||||
|
[array]$octets = $IPAddress.Split('.')
|
||||||
|
return [int]($octets[0]) * 16777216 + [int]($octets[1]) * 65536 + [int]($octets[2]) * 256 + [int]($octets[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
# Convert integer back to IP address
|
||||||
|
function Convert-IntToIP {
|
||||||
|
param (
|
||||||
|
[int64]$Integer
|
||||||
|
)
|
||||||
|
$octet1 = [Math]::Floor($Integer / 16777216)
|
||||||
|
$remainder = $Integer % 16777216
|
||||||
|
$octet2 = [Math]::Floor($remainder / 65536)
|
||||||
|
$remainder = $remainder % 65536
|
||||||
|
$octet3 = [Math]::Floor($remainder / 256)
|
||||||
|
$octet4 = $remainder % 256
|
||||||
|
return "$octet1.$octet2.$octet3.$octet4"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get subnet range based on IP and mask
|
||||||
|
function Get-SubnetRange {
|
||||||
|
param (
|
||||||
|
[string]$IPAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assuming /24 subnet
|
||||||
|
$octets = $IPAddress.Split('.')
|
||||||
|
$networkPrefix = "$($octets[0]).$($octets[1]).$($octets[2])"
|
||||||
|
$rangeStart = "$networkPrefix.1"
|
||||||
|
$rangeEnd = "$networkPrefix.254"
|
||||||
|
|
||||||
|
return @{
|
||||||
|
Start = $rangeStart
|
||||||
|
End = $rangeEnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get available DNS servers
|
||||||
|
function Get-AvailableDnsServers {
|
||||||
|
# $dnsServers = @("localhost")
|
||||||
|
|
||||||
|
$clientDnsServers = Get-DnsClientServerAddress |
|
||||||
|
Where-Object { $_.ServerAddresses -ne $null } |
|
||||||
|
ForEach-Object {
|
||||||
|
$_.ServerAddresses | Where-Object { $_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' }
|
||||||
|
} |
|
||||||
|
Select-Object -Unique
|
||||||
|
|
||||||
|
$dnsServers += $clientDnsServers
|
||||||
|
|
||||||
|
# Try to add domain controllers if we're in a domain environment
|
||||||
|
try {
|
||||||
|
$domainControllers = Get-ADDomainController -Filter * |
|
||||||
|
ForEach-Object { $_.HostName }
|
||||||
|
$dnsServers += $domainControllers
|
||||||
|
} catch {
|
||||||
|
# Not in a domain environment or AD module not available, continue without it
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dnsServers | Select-Object -Unique
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query DNS for records
|
||||||
|
function Search-DnsRecords {
|
||||||
|
param (
|
||||||
|
[string]$DnsServer,
|
||||||
|
[string]$IPRangeStart,
|
||||||
|
[string]$IPRangeEnd
|
||||||
|
)
|
||||||
|
|
||||||
|
$StartInt = Convert-IPToInt $IPRangeStart
|
||||||
|
$EndInt = Convert-IPToInt $IPRangeEnd
|
||||||
|
|
||||||
|
$Results = @()
|
||||||
|
|
||||||
|
try {
|
||||||
|
$Zones = Get-DnsServerZone -ComputerName $DnsServer -ErrorAction Stop
|
||||||
|
|
||||||
|
foreach ($Zone in $Zones) {
|
||||||
|
$Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ComputerName $DnsServer -ErrorAction SilentlyContinue
|
||||||
|
foreach ($Record in $Records) {
|
||||||
|
if ($Record.RecordType -eq "A") {
|
||||||
|
$IPInt = Convert-IPToInt $Record.RecordData.IPv4Address.ToString()
|
||||||
|
if ($IPInt -ge $StartInt -and $IPInt -le $EndInt) {
|
||||||
|
$Results += [PSCustomObject]@{
|
||||||
|
IPAddress = $Record.RecordData.IPv4Address
|
||||||
|
Hostname = $Record.HostName
|
||||||
|
Zone = $Zone.ZoneName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("Error querying DNS server: $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Results
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the main form
|
||||||
|
$form = New-Object System.Windows.Forms.Form
|
||||||
|
$form.Text = "Cartographer - DNS Record Mapping Tool"
|
||||||
|
$form.Size = New-Object System.Drawing.Size(800, 600)
|
||||||
|
$form.StartPosition = "CenterScreen"
|
||||||
|
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||||||
|
$form.MaximizeBox = $false
|
||||||
|
|
||||||
|
# DNS Server selection
|
||||||
|
$dnsServerLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$dnsServerLabel.Text = "DNS Server:"
|
||||||
|
$dnsServerLabel.Location = New-Object System.Drawing.Point(20, 20)
|
||||||
|
$dnsServerLabel.Size = New-Object System.Drawing.Size(100, 20)
|
||||||
|
$form.Controls.Add($dnsServerLabel)
|
||||||
|
|
||||||
|
$dnsServerComboBox = New-Object System.Windows.Forms.ComboBox
|
||||||
|
$dnsServerComboBox.Location = New-Object System.Drawing.Point(130, 20)
|
||||||
|
$dnsServerComboBox.Size = New-Object System.Drawing.Size(200, 20)
|
||||||
|
$dnsServerComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
|
||||||
|
$form.Controls.Add($dnsServerComboBox)
|
||||||
|
|
||||||
|
# Populate DNS Server dropdown
|
||||||
|
$dnsServers = Get-AvailableDnsServers
|
||||||
|
foreach ($server in $dnsServers) {
|
||||||
|
$dnsServerComboBox.Items.Add($server)
|
||||||
|
}
|
||||||
|
if ($dnsServerComboBox.Items.Count -gt 0) {
|
||||||
|
$dnsServerComboBox.SelectedIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# IP Range Selection Group
|
||||||
|
$ipRangeGroupBox = New-Object System.Windows.Forms.GroupBox
|
||||||
|
$ipRangeGroupBox.Text = "IP Range Selection"
|
||||||
|
$ipRangeGroupBox.Location = New-Object System.Drawing.Point(20, 50)
|
||||||
|
$ipRangeGroupBox.Size = New-Object System.Drawing.Size(750, 120)
|
||||||
|
$form.Controls.Add($ipRangeGroupBox)
|
||||||
|
|
||||||
|
# Radio buttons for range selection
|
||||||
|
$subnetRadioButton = New-Object System.Windows.Forms.RadioButton
|
||||||
|
$subnetRadioButton.Text = "Scan Full /24 Subnet"
|
||||||
|
$subnetRadioButton.Location = New-Object System.Drawing.Point(20, 20)
|
||||||
|
$subnetRadioButton.Size = New-Object System.Drawing.Size(150, 20)
|
||||||
|
$subnetRadioButton.Checked = $true
|
||||||
|
$ipRangeGroupBox.Controls.Add($subnetRadioButton)
|
||||||
|
|
||||||
|
$customRangeRadioButton = New-Object System.Windows.Forms.RadioButton
|
||||||
|
$customRangeRadioButton.Text = "Custom IP Range"
|
||||||
|
$customRangeRadioButton.Location = New-Object System.Drawing.Point(20, 50)
|
||||||
|
$customRangeRadioButton.Size = New-Object System.Drawing.Size(150, 20)
|
||||||
|
$ipRangeGroupBox.Controls.Add($customRangeRadioButton)
|
||||||
|
|
||||||
|
# Subnet IP entry
|
||||||
|
$subnetIPLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$subnetIPLabel.Text = "Subnet IP Address:"
|
||||||
|
$subnetIPLabel.Location = New-Object System.Drawing.Point(180, 20)
|
||||||
|
$subnetIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||||
|
$ipRangeGroupBox.Controls.Add($subnetIPLabel)
|
||||||
|
|
||||||
|
$subnetIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$subnetIPTextBox.Location = New-Object System.Drawing.Point(300, 20)
|
||||||
|
$subnetIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||||
|
$subnetIPTextBox.Text = "192.168.1.1"
|
||||||
|
$ipRangeGroupBox.Controls.Add($subnetIPTextBox)
|
||||||
|
|
||||||
|
# Custom range IP entries
|
||||||
|
$startIPLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$startIPLabel.Text = "Start IP Address:"
|
||||||
|
$startIPLabel.Location = New-Object System.Drawing.Point(180, 50)
|
||||||
|
$startIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||||
|
$ipRangeGroupBox.Controls.Add($startIPLabel)
|
||||||
|
|
||||||
|
$startIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$startIPTextBox.Location = New-Object System.Drawing.Point(300, 50)
|
||||||
|
$startIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||||
|
$startIPTextBox.Text = "192.168.1.1"
|
||||||
|
$startIPTextBox.Enabled = $false
|
||||||
|
$ipRangeGroupBox.Controls.Add($startIPTextBox)
|
||||||
|
|
||||||
|
$endIPLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$endIPLabel.Text = "End IP Address:"
|
||||||
|
$endIPLabel.Location = New-Object System.Drawing.Point(460, 50)
|
||||||
|
$endIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||||
|
$ipRangeGroupBox.Controls.Add($endIPLabel)
|
||||||
|
|
||||||
|
$endIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$endIPTextBox.Location = New-Object System.Drawing.Point(580, 50)
|
||||||
|
$endIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||||
|
$endIPTextBox.Text = "192.168.1.254"
|
||||||
|
$endIPTextBox.Enabled = $false
|
||||||
|
$ipRangeGroupBox.Controls.Add($endIPTextBox)
|
||||||
|
|
||||||
|
# Radio button event handlers
|
||||||
|
$subnetRadioButton.Add_CheckedChanged({
|
||||||
|
if ($subnetRadioButton.Checked) {
|
||||||
|
$subnetIPTextBox.Enabled = $true
|
||||||
|
$startIPTextBox.Enabled = $false
|
||||||
|
$endIPTextBox.Enabled = $false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$customRangeRadioButton.Add_CheckedChanged({
|
||||||
|
if ($customRangeRadioButton.Checked) {
|
||||||
|
$subnetIPTextBox.Enabled = $false
|
||||||
|
$startIPTextBox.Enabled = $true
|
||||||
|
$endIPTextBox.Enabled = $true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Auto-calculate subnet range from subnet IP
|
||||||
|
$subnetIPTextBox.Add_TextChanged({
|
||||||
|
if ($subnetRadioButton.Checked -and $subnetIPTextBox.Text -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') {
|
||||||
|
$range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text
|
||||||
|
$startIPTextBox.Text = $range.Start
|
||||||
|
$endIPTextBox.Text = $range.End
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Search Button
|
||||||
|
$searchButton = New-Object System.Windows.Forms.Button
|
||||||
|
$searchButton.Text = "Search DNS Records"
|
||||||
|
$searchButton.Location = New-Object System.Drawing.Point(20, 180)
|
||||||
|
$searchButton.Size = New-Object System.Drawing.Size(150, 30)
|
||||||
|
$form.Controls.Add($searchButton)
|
||||||
|
|
||||||
|
# Status Label
|
||||||
|
$statusLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$statusLabel.Text = "Ready"
|
||||||
|
$statusLabel.Location = New-Object System.Drawing.Point(180, 185)
|
||||||
|
$statusLabel.Size = New-Object System.Drawing.Size(590, 20)
|
||||||
|
$form.Controls.Add($statusLabel)
|
||||||
|
|
||||||
|
# Results DataGridView
|
||||||
|
$resultsDataGridView = New-Object System.Windows.Forms.DataGridView
|
||||||
|
$resultsDataGridView.Location = New-Object System.Drawing.Point(20, 220)
|
||||||
|
$resultsDataGridView.Size = New-Object System.Drawing.Size(750, 300)
|
||||||
|
$resultsDataGridView.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::Fill
|
||||||
|
$resultsDataGridView.AllowUserToAddRows = $false
|
||||||
|
$resultsDataGridView.AllowUserToDeleteRows = $false
|
||||||
|
$resultsDataGridView.ReadOnly = $true
|
||||||
|
$resultsDataGridView.MultiSelect = $false
|
||||||
|
$resultsDataGridView.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect
|
||||||
|
$form.Controls.Add($resultsDataGridView)
|
||||||
|
|
||||||
|
# Export Button
|
||||||
|
$exportButton = New-Object System.Windows.Forms.Button
|
||||||
|
$exportButton.Text = "Export Results"
|
||||||
|
$exportButton.Location = New-Object System.Drawing.Point(20, 530)
|
||||||
|
$exportButton.Size = New-Object System.Drawing.Size(120, 30)
|
||||||
|
$exportButton.Enabled = $false
|
||||||
|
$form.Controls.Add($exportButton)
|
||||||
|
|
||||||
|
# Search button click event
|
||||||
|
$searchButton.Add_Click({
|
||||||
|
$statusLabel.Text = "Searching DNS records..."
|
||||||
|
$resultsDataGridView.DataSource = $null
|
||||||
|
$exportButton.Enabled = $false
|
||||||
|
|
||||||
|
$selectedDnsServer = $dnsServerComboBox.SelectedItem.ToString()
|
||||||
|
|
||||||
|
$ipRangeStart = ""
|
||||||
|
$ipRangeEnd = ""
|
||||||
|
|
||||||
|
if ($subnetRadioButton.Checked) {
|
||||||
|
$range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text
|
||||||
|
$ipRangeStart = $range.Start
|
||||||
|
$ipRangeEnd = $range.End
|
||||||
|
} else {
|
||||||
|
$ipRangeStart = $startIPTextBox.Text
|
||||||
|
$ipRangeEnd = $endIPTextBox.Text
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = Search-DnsRecords -DnsServer $selectedDnsServer -IPRangeStart $ipRangeStart -IPRangeEnd $ipRangeEnd
|
||||||
|
|
||||||
|
if ($results.Count -gt 0) {
|
||||||
|
$dataTable = New-Object System.Data.DataTable
|
||||||
|
$dataTable.Columns.Add("IPAddress", [string])
|
||||||
|
$dataTable.Columns.Add("Hostname", [string])
|
||||||
|
$dataTable.Columns.Add("Zone", [string])
|
||||||
|
|
||||||
|
foreach ($result in $results) {
|
||||||
|
$dataTable.Rows.Add($result.IPAddress.ToString(), $result.Hostname, $result.Zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultsDataGridView.DataSource = $dataTable
|
||||||
|
$statusLabel.Text = "Found $($results.Count) DNS records"
|
||||||
|
$exportButton.Enabled = $true
|
||||||
|
} else {
|
||||||
|
$statusLabel.Text = "No DNS records found in the specified range"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Export button click event
|
||||||
|
$exportButton.Add_Click({
|
||||||
|
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
|
||||||
|
$saveFileDialog.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*"
|
||||||
|
$saveFileDialog.Title = "Export DNS Records"
|
||||||
|
$saveFileDialog.FileName = "DNSRecords_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
|
||||||
|
|
||||||
|
if ($saveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
||||||
|
$dataTable = $resultsDataGridView.DataSource
|
||||||
|
$dataTable | Export-Csv -Path $saveFileDialog.FileName -NoTypeInformation
|
||||||
|
$statusLabel.Text = "Exported to $($saveFileDialog.FileName)"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Show the form
|
||||||
|
[void]$form.ShowDialog()
|
||||||
|
|
||||||
203
Contrast.ps1
Normal file
203
Contrast.ps1
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
|
||||||
|
#Set Domain Controller Variable
|
||||||
|
|
||||||
|
$domaincontroller = "fqdn.domain.placeholder" ##################### UPDATE THIS LINE #####################
|
||||||
|
|
||||||
|
# Create a form
|
||||||
|
$form = New-Object Windows.Forms.Form
|
||||||
|
$form.Text = "Compare AD Group Memberships"
|
||||||
|
$form.Width = 600
|
||||||
|
$form.Height = 900
|
||||||
|
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
|
||||||
|
|
||||||
|
# Signature for UPNs
|
||||||
|
$labelSignature = New-Object Windows.Forms.Label
|
||||||
|
$labelSignature.Text = "Made by Zak Bearman - Intel"
|
||||||
|
$labelSignature.Location = New-Object Drawing.Point(10, 832)
|
||||||
|
$form.Controls.Add($labelSignature)
|
||||||
|
|
||||||
|
# Labels and Textboxes for UPNs
|
||||||
|
$labelPrimaryUser = New-Object Windows.Forms.Label
|
||||||
|
$labelPrimaryUser.Text = "Primary User UPN:"
|
||||||
|
$labelPrimaryUser.Location = New-Object Drawing.Point(10, 23)
|
||||||
|
$form.Controls.Add($labelPrimaryUser)
|
||||||
|
|
||||||
|
$textBoxPrimaryUser = New-Object Windows.Forms.TextBox
|
||||||
|
$textBoxPrimaryUser.Location = New-Object Drawing.Point(120, 20)
|
||||||
|
$textBoxPrimaryUser.Width = 200
|
||||||
|
$form.Controls.Add($textBoxPrimaryUser)
|
||||||
|
|
||||||
|
# ComboBox for selecting the number of users to compare against
|
||||||
|
$labelNumUsers = New-Object Windows.Forms.Label
|
||||||
|
$labelNumUsers.Text = "How many other users?"
|
||||||
|
$labelNumUsers.Location = New-Object Drawing.Point(10, 50)
|
||||||
|
$form.Controls.Add($labelNumUsers)
|
||||||
|
|
||||||
|
$comboBoxNumUsers = New-Object Windows.Forms.ComboBox
|
||||||
|
$comboBoxNumUsers.Location = New-Object Drawing.Point(250, 50)
|
||||||
|
$comboBoxNumUsers.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
|
||||||
|
$comboBoxNumUsers.Items.Add("1")
|
||||||
|
$comboBoxNumUsers.Items.Add("2")
|
||||||
|
$comboBoxNumUsers.Items.Add("3")
|
||||||
|
$comboBoxNumUsers.SelectedIndex = 0
|
||||||
|
$form.Controls.Add($comboBoxNumUsers)
|
||||||
|
|
||||||
|
# GroupBox for UPNs of users to compare against
|
||||||
|
$groupBoxUsers = New-Object Windows.Forms.GroupBox
|
||||||
|
$groupBoxUsers.Text = "Users to Compare Against:"
|
||||||
|
$groupBoxUsers.Location = New-Object Drawing.Point(10, 80)
|
||||||
|
$groupBoxUsers.Width = 340
|
||||||
|
$groupBoxUsers.Height = 100
|
||||||
|
$form.Controls.Add($groupBoxUsers)
|
||||||
|
|
||||||
|
# Textboxes for entering UPNs based on the selected number of users
|
||||||
|
$textBoxUser1 = New-Object Windows.Forms.TextBox
|
||||||
|
$textBoxUser1.Location = New-Object Drawing.Point(10, 20)
|
||||||
|
$textBoxUser1.Width = 200
|
||||||
|
$groupBoxUsers.Controls.Add($textBoxUser1)
|
||||||
|
|
||||||
|
$textBoxUser2 = New-Object Windows.Forms.TextBox
|
||||||
|
$textBoxUser2.Location = New-Object Drawing.Point(10, 50)
|
||||||
|
$textBoxUser2.Width = 200
|
||||||
|
$textBoxUser2.Visible = $false
|
||||||
|
$groupBoxUsers.Controls.Add($textBoxUser2)
|
||||||
|
|
||||||
|
$textBoxUser3 = New-Object Windows.Forms.TextBox
|
||||||
|
$textBoxUser3.Location = New-Object Drawing.Point(10, 80)
|
||||||
|
$textBoxUser3.Width = 200
|
||||||
|
$textBoxUser3.Visible = $false
|
||||||
|
$groupBoxUsers.Controls.Add($textBoxUser3)
|
||||||
|
|
||||||
|
# Button to initiate comparison
|
||||||
|
$buttonCompare = New-Object Windows.Forms.Button
|
||||||
|
$buttonCompare.Text = "Compare"
|
||||||
|
$buttonCompare.Location = New-Object Drawing.Point(120, 195)
|
||||||
|
$form.Controls.Add($buttonCompare)
|
||||||
|
|
||||||
|
# Help button to display usage instructions
|
||||||
|
$buttonHelp = New-Object Windows.Forms.Button
|
||||||
|
$buttonHelp.Text = "Click Me"
|
||||||
|
$buttonHelp.Location = New-Object Drawing.Point(215, 195)
|
||||||
|
$form.Controls.Add($buttonHelp)
|
||||||
|
|
||||||
|
# Scrollable and selectable textbox for displaying output
|
||||||
|
$textBoxOutput = New-Object Windows.Forms.TextBox
|
||||||
|
$textBoxOutput.Location = New-Object Drawing.Point(10, 230)
|
||||||
|
$textBoxOutput.Width = 560
|
||||||
|
$textBoxOutput.Height = 600
|
||||||
|
$textBoxOutput.Multiline = $true
|
||||||
|
$textBoxOutput.ScrollBars = "Vertical"
|
||||||
|
$textBoxOutput.ReadOnly = $true
|
||||||
|
$form.Controls.Add($textBoxOutput)
|
||||||
|
|
||||||
|
# Event handler for the ComboBox selection change
|
||||||
|
$comboBoxNumUsers.Add_SelectedIndexChanged({
|
||||||
|
$numUsers = [int]$comboBoxNumUsers.SelectedItem
|
||||||
|
|
||||||
|
# Show/hide textboxes based on the selected number of users
|
||||||
|
$textBoxUser1.Visible = $numUsers -ge 1
|
||||||
|
$textBoxUser2.Visible = $numUsers -ge 2
|
||||||
|
$textBoxUser3.Visible = $numUsers -ge 3
|
||||||
|
})
|
||||||
|
|
||||||
|
# Event handler for the Compare button
|
||||||
|
$buttonCompare.Add_Click({
|
||||||
|
# Get the entered UPNs and the selected number of users
|
||||||
|
$primaryUserUPN = $textBoxPrimaryUser.Text
|
||||||
|
$numUsers = [int]$comboBoxNumUsers.SelectedItem
|
||||||
|
|
||||||
|
# Get the UPNs of the users to compare against based on the selected number
|
||||||
|
$usersToCompareUPNs = @()
|
||||||
|
if ($textBoxUser1.Visible) { $usersToCompareUPNs += $textBoxUser1.Text }
|
||||||
|
if ($textBoxUser2.Visible) { $usersToCompareUPNs += $textBoxUser2.Text }
|
||||||
|
if ($textBoxUser3.Visible) { $usersToCompareUPNs += $textBoxUser3.Text }
|
||||||
|
|
||||||
|
# Function to get group memberships for a user using UPN
|
||||||
|
function Get-ADUserGroupsByUPN {
|
||||||
|
param (
|
||||||
|
[string]$userUPN
|
||||||
|
)
|
||||||
|
|
||||||
|
$user = Get-ADUser -Filter { UserPrincipalName -eq $userUPN } -Server $domaincontroller
|
||||||
|
if ($user) {
|
||||||
|
$groups = Get-ADPrincipalGroupMembership -Identity $user -Server $domaincontroller
|
||||||
|
return $groups | Select-Object -ExpandProperty Name
|
||||||
|
} else {
|
||||||
|
Write-Host "User with UPN $userUPN not found."
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get group memberships for the primary user
|
||||||
|
$primaryUserGroups = Get-ADUserGroupsByUPN -userUPN $primaryUserUPN
|
||||||
|
|
||||||
|
if ($primaryUserGroups -ne $null) {
|
||||||
|
# Compare group memberships for the primary user with other users
|
||||||
|
$missingGroups = @()
|
||||||
|
|
||||||
|
foreach ($userUPN in $usersToCompareUPNs) {
|
||||||
|
$userGroups = Get-ADUserGroupsByUPN -userUPN $userUPN
|
||||||
|
if ($userGroups -ne $null) {
|
||||||
|
foreach ($group in $userGroups) {
|
||||||
|
if ($primaryUserGroups -notcontains $group -and $missingGroups -notcontains $group) {
|
||||||
|
$missingGroups += $group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display the missing groups in the output textbox
|
||||||
|
if ($missingGroups.Count -gt 0) {
|
||||||
|
$missingGroupsText = $missingGroups -join "`r`n"
|
||||||
|
$textBoxOutput.Text = "Groups missing for $primaryUserUPN compared to the other users:`r`n`r`n$missingGroupsText"
|
||||||
|
} else {
|
||||||
|
$textBoxOutput.Text = "No missing groups found for $primaryUserUPN."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Event handler for the Help button
|
||||||
|
$buttonHelp.Add_Click({
|
||||||
|
# Display usage instructions in a new window
|
||||||
|
$helpForm = New-Object Windows.Forms.Form
|
||||||
|
$helpForm.Text = "Usage Instructions"
|
||||||
|
$helpForm.Width = 400
|
||||||
|
$helpForm.Height = 350
|
||||||
|
|
||||||
|
$helpLabel = New-Object Windows.Forms.Label
|
||||||
|
$helpLabel.Text = "Instructions:"
|
||||||
|
$helpLabel.Location = New-Object Drawing.Point(10, 10)
|
||||||
|
$helpForm.Controls.Add($helpLabel)
|
||||||
|
|
||||||
|
$helpText = @"
|
||||||
|
1. Enter the UPN of the primary user in the 'Primary User UPN' field.
|
||||||
|
|
||||||
|
2. Select the number of users to compare against from the dropdown 1, 2 or 3.
|
||||||
|
|
||||||
|
3. Enter the UPNs of the users to compare against in the 'Users to Compare Against' section.
|
||||||
|
|
||||||
|
4. Click the 'Compare' button to compare group memberships that the primary user is missing.
|
||||||
|
|
||||||
|
5. The results will be displayed in the textbox below. Find the membership that is most likely what they need and apply this in AD.
|
||||||
|
|
||||||
|
6. If this is an admin account, Please supply this information to Wintel via the ticket to be actioned accordingly.
|
||||||
|
"@
|
||||||
|
$helpTextBox = New-Object Windows.Forms.TextBox
|
||||||
|
$helpTextBox.Location = New-Object Drawing.Point(10, 40)
|
||||||
|
$helpTextBox.Width = 360
|
||||||
|
$helpTextBox.Height = 250
|
||||||
|
$helpTextBox.Multiline = $true
|
||||||
|
$helpTextBox.ScrollBars = "Vertical"
|
||||||
|
$helpTextBox.Text = $helpText
|
||||||
|
$helpTextBox.ReadOnly = $true
|
||||||
|
$helpForm.Controls.Add($helpTextBox)
|
||||||
|
|
||||||
|
$helpForm.ShowDialog()
|
||||||
|
})
|
||||||
|
|
||||||
|
# Show the form
|
||||||
|
$form.ShowDialog()
|
||||||
|
|
||||||
|
|
||||||
|
# Disclaimer: TWFkZSBieSBaYWsgQmVhcm1hbiAtIERhdGFjb20gV2ludGVsIC0gUHJvdmlkZWQgYXMgaXMgd2hlcmUgaXMuIElmIGJyb2tlbiB3aWxsIGJlIGxvb2tlZCBhdCBpbiBhIGJlc3QgZWZmb3J0IGF0dGVtcHQ=
|
||||||
80
Conversation.ps1
Normal file
80
Conversation.ps1
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
## After running the powershell scriopt run the following after the fact changing the port number to what you need.
|
||||||
|
|
||||||
|
## $msg = Receive-TCPMessage -Port 9999
|
||||||
|
|
||||||
|
## from the remote server that you need to send the traffic from. Run the following with the port number you set to listen
|
||||||
|
|
||||||
|
## Test-NetConnection win1962 -Port 9999
|
||||||
|
|
||||||
|
Function Receive-TCPMessage {
|
||||||
|
|
||||||
|
Param (
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true, Position=0)]
|
||||||
|
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
|
||||||
|
[int] $Port
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
Process {
|
||||||
|
|
||||||
|
Try {
|
||||||
|
|
||||||
|
# Set up endpoint and start listening
|
||||||
|
|
||||||
|
$endpoint = new-object System.Net.IPEndPoint([ipaddress]::any,$port)
|
||||||
|
|
||||||
|
$listener = new-object System.Net.Sockets.TcpListener $EndPoint
|
||||||
|
|
||||||
|
$listener.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Wait for an incoming connection
|
||||||
|
|
||||||
|
$data = $listener.AcceptTcpClient()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Stream setup
|
||||||
|
|
||||||
|
$stream = $data.GetStream()
|
||||||
|
|
||||||
|
$bytes = New-Object System.Byte[] 1024
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Read data from stream and write it to host
|
||||||
|
|
||||||
|
while (($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){
|
||||||
|
|
||||||
|
$EncodedText = New-Object System.Text.ASCIIEncoding
|
||||||
|
|
||||||
|
$data = $EncodedText.GetString($bytes,0, $i)
|
||||||
|
|
||||||
|
Write-Output $data
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Close TCP connection and stop listening
|
||||||
|
|
||||||
|
$stream.close()
|
||||||
|
|
||||||
|
$listener.stop()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Catch {
|
||||||
|
|
||||||
|
"Receive Message failed with: `n" + $Error[0]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
111
Darth-SPooN.ps1
Normal file
111
Darth-SPooN.ps1
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$MachineName,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ServiceAccount,
|
||||||
|
|
||||||
|
[int]$SqlPort = 1433,
|
||||||
|
|
||||||
|
[string[]]$HadrListeners
|
||||||
|
)
|
||||||
|
|
||||||
|
Import-Module ActiveDirectory
|
||||||
|
|
||||||
|
Write-Host "=== MSSQLSvc + HADR SPN Validation Tool ===" -ForegroundColor Cyan
|
||||||
|
Write-Host "Machine: $MachineName"
|
||||||
|
Write-Host "Service Account: $ServiceAccount"
|
||||||
|
Write-Host "SQL Port: $SqlPort"
|
||||||
|
if ($HadrListeners) {
|
||||||
|
Write-Host "HADR Listener(s): $($HadrListeners -join ', ')"
|
||||||
|
}
|
||||||
|
Write-Host "-------------------------------------------"
|
||||||
|
|
||||||
|
# Get domain FQDN
|
||||||
|
$domainFQDN = (Get-ADDomain).DNSRoot
|
||||||
|
|
||||||
|
# Lookup service account (user or computer)
|
||||||
|
try {
|
||||||
|
$svcObj = Get-ADUser -Identity $ServiceAccount -Properties ServicePrincipalName -ErrorAction Stop
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
$svcObj = Get-ADComputer -Identity $ServiceAccount -Properties ServicePrincipalName -ErrorAction Stop
|
||||||
|
} catch {
|
||||||
|
Write-Host "ERROR: Service account '$ServiceAccount' not found in AD." -ForegroundColor Red
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build expected MSSQLSvc SPNs for machine and HADR listeners
|
||||||
|
$namesToCheck = @($MachineName)
|
||||||
|
if ($HadrListeners) {
|
||||||
|
$namesToCheck += $HadrListeners
|
||||||
|
}
|
||||||
|
$expectedSPNs = foreach ($name in $namesToCheck) {
|
||||||
|
"MSSQLSvc/${name}.${domainFQDN}:$SqlPort"
|
||||||
|
"MSSQLSvc/${name}:$SqlPort"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nExpected MSSQLSvc SPNs:" -ForegroundColor Yellow
|
||||||
|
$expectedSPNs | ForEach-Object { Write-Host " $_" }
|
||||||
|
|
||||||
|
# Case-insensitive missing SPN check (fixed grouping)
|
||||||
|
$missingSPNs = $expectedSPNs | Where-Object {
|
||||||
|
$expectedLower = $_.ToLower()
|
||||||
|
-not (( $svcObj.ServicePrincipalName | ForEach-Object { $_.ToLower() } ) -contains $expectedLower)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($missingSPNs) {
|
||||||
|
Write-Host "`n[!] Missing MSSQLSvc SPNs on service account:" -ForegroundColor Red
|
||||||
|
$missingSPNs | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
|
||||||
|
|
||||||
|
$addPrompt = Read-Host "`nDo you want to add the missing SPNs now? (Y/N)"
|
||||||
|
if ($addPrompt -match '^[Yy]$') {
|
||||||
|
foreach ($spn in $missingSPNs) {
|
||||||
|
Write-Host "Adding SPN: $spn" -ForegroundColor Green
|
||||||
|
# Use -S to avoid duplicates, requires running as an account with permission
|
||||||
|
setspn -S $spn $ServiceAccount
|
||||||
|
}
|
||||||
|
Write-Host "`n[OK] Missing SPNs have been added." -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "Skipping SPN creation." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "`n[OK] All expected MSSQLSvc SPNs are present." -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pull all SPNs in the domain
|
||||||
|
$allSPNs = Get-ADObject -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName |
|
||||||
|
ForEach-Object {
|
||||||
|
foreach ($spn in $_.ServicePrincipalName) {
|
||||||
|
[PSCustomObject]@{
|
||||||
|
SPN = $spn
|
||||||
|
ADObject = $_.SamAccountName
|
||||||
|
DN = $_.DistinguishedName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for duplicates of MSSQLSvc SPNs
|
||||||
|
Write-Host "`nChecking for duplicate MSSQLSvc SPNs in the domain..." -ForegroundColor Yellow
|
||||||
|
foreach ($spn in $svcObj.ServicePrincipalName | Where-Object { $_ -like "MSSQLSvc/*" }) {
|
||||||
|
$owners = $allSPNs | Where-Object { $_.SPN -eq $spn }
|
||||||
|
if ($owners.Count -gt 1) {
|
||||||
|
Write-Host "[DUPLICATE] SPN '$spn' is owned by multiple objects:" -ForegroundColor Red
|
||||||
|
$owners | ForEach-Object { Write-Host " -> $($_.ADObject) ($($_.DN))" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for MSSQLSvc SPNs on service account that aren't expected
|
||||||
|
$expectedLowerList = $expectedSPNs | ForEach-Object { $_.ToLower() }
|
||||||
|
$wrongSPNs = $svcObj.ServicePrincipalName | Where-Object {
|
||||||
|
$_ -like "MSSQLSvc/*" -and ($_.ToLower() -notin $expectedLowerList)
|
||||||
|
}
|
||||||
|
if ($wrongSPNs) {
|
||||||
|
Write-Host "`n[!] Warning: Service account has MSSQLSvc SPNs not in expected list:" -ForegroundColor Red
|
||||||
|
$wrongSPNs | ForEach-Object { Write-Host " $_" }
|
||||||
|
} else {
|
||||||
|
Write-Host "`n[OK] No unexpected MSSQLSvc SPNs found." -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`n=== MSSQLSvc + HADR SPN Check Complete ==="
|
||||||
132
EggBasket.ps1
Normal file
132
EggBasket.ps1
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Load required assemblies
|
||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
|
||||||
|
# Create the form
|
||||||
|
$form = New-Object System.Windows.Forms.Form
|
||||||
|
$form.Text = "MSA Creator - Khan Mayker"
|
||||||
|
$form.Size = New-Object System.Drawing.Size(400,400)
|
||||||
|
$form.StartPosition = "CenterScreen"
|
||||||
|
|
||||||
|
# Create Labels and Textboxes for Variables
|
||||||
|
$labelSVCAccount = New-Object System.Windows.Forms.Label
|
||||||
|
$labelSVCAccount.Text = "Service Account Name:"
|
||||||
|
$labelSVCAccount.Location = New-Object System.Drawing.Point(10,20)
|
||||||
|
$labelSVCAccount.Size = New-Object System.Drawing.Size(150,20)
|
||||||
|
$form.Controls.Add($labelSVCAccount)
|
||||||
|
|
||||||
|
$textSVCAccount = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textSVCAccount.Location = New-Object System.Drawing.Point(180,20)
|
||||||
|
$textSVCAccount.Size = New-Object System.Drawing.Size(180,20)
|
||||||
|
$form.Controls.Add($textSVCAccount)
|
||||||
|
|
||||||
|
$labelDNS = New-Object System.Windows.Forms.Label
|
||||||
|
$labelDNS.Text = "DNS Host Name:"
|
||||||
|
$labelDNS.Location = New-Object System.Drawing.Point(10,60)
|
||||||
|
$labelDNS.Size = New-Object System.Drawing.Size(150,20)
|
||||||
|
$form.Controls.Add($labelDNS)
|
||||||
|
|
||||||
|
$textDNS = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textDNS.Location = New-Object System.Drawing.Point(180,60)
|
||||||
|
$textDNS.Size = New-Object System.Drawing.Size(180,20)
|
||||||
|
$textDNS.Text = ".domain.placeholder.nz" # Enter your domain "domain.govt.nz" ##################### UPDATE THIS LINE #####################
|
||||||
|
$textDNS.Enabled = $false
|
||||||
|
$form.Controls.Add($textDNS)
|
||||||
|
|
||||||
|
$labelPath = New-Object System.Windows.Forms.Label
|
||||||
|
$labelPath.Text = "OU Path:"
|
||||||
|
$labelPath.Location = New-Object System.Drawing.Point(10,100)
|
||||||
|
$labelPath.Size = New-Object System.Drawing.Size(150,20)
|
||||||
|
$form.Controls.Add($labelPath)
|
||||||
|
|
||||||
|
$textPath = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textPath.Location = New-Object System.Drawing.Point(180,100)
|
||||||
|
$textPath.Size = New-Object System.Drawing.Size(180,20)
|
||||||
|
$textPath.Text = "OU=grMSA,OU=Service Accounts,OU=_Administration,DC=domain,DC=placeholder,DC=nz" ##################### UPDATE THIS LINE #####################
|
||||||
|
$textPath.Enabled = $false
|
||||||
|
$form.Controls.Add($textPath)
|
||||||
|
|
||||||
|
$labelMachines = New-Object System.Windows.Forms.Label
|
||||||
|
$labelMachines.Text = "Machine Names (comma-separated):"
|
||||||
|
$labelMachines.Location = New-Object System.Drawing.Point(10,140)
|
||||||
|
$labelMachines.Size = New-Object System.Drawing.Size(220,20)
|
||||||
|
$form.Controls.Add($labelMachines)
|
||||||
|
|
||||||
|
$textMachines = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textMachines.Location = New-Object System.Drawing.Point(10,170)
|
||||||
|
$textMachines.Size = New-Object System.Drawing.Size(350,20)
|
||||||
|
$form.Controls.Add($textMachines)
|
||||||
|
|
||||||
|
# Event to update DNS field based on Service Account Name input
|
||||||
|
$textSVCAccount.Add_TextChanged({
|
||||||
|
$textDNS.Text = "$($textSVCAccount.Text).domain.placeholder.nz" ##################### UPDATE THIS LINE #####################
|
||||||
|
})
|
||||||
|
|
||||||
|
# Create the Submit Button
|
||||||
|
$buttonSubmit = New-Object System.Windows.Forms.Button
|
||||||
|
$buttonSubmit.Text = "Create MSA and AD Group"
|
||||||
|
$buttonSubmit.Location = New-Object System.Drawing.Point(120, 210)
|
||||||
|
$buttonSubmit.Size = New-Object System.Drawing.Size(150,30)
|
||||||
|
$form.Controls.Add($buttonSubmit)
|
||||||
|
|
||||||
|
# Action on Submit Button Click
|
||||||
|
$buttonSubmit.Add_Click({
|
||||||
|
$SVCAccount = $textSVCAccount.Text
|
||||||
|
$dns = $textDNS.Text
|
||||||
|
$path = "OU=grMSA,OU=Service Accounts,OU=_Administration,DC=domain,DC=placeholder,DC=nz" ##################### UPDATE THIS LINE #####################
|
||||||
|
$machines = $textMachines.Text.Split(',')
|
||||||
|
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($SVCAccount) -and -not [string]::IsNullOrWhiteSpace($dns) -and -not [string]::IsNullOrWhiteSpace($path) -and $machines.Count -gt 0) {
|
||||||
|
|
||||||
|
$grMSA = "grMSA_$SVCAccount"
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Create AD Group
|
||||||
|
New-ADGroup -Name $grMSA -Path $path -GroupScope Global -PassThru -Verbose
|
||||||
|
|
||||||
|
# Add Machines to AD Group
|
||||||
|
foreach ($machine in $machines) {
|
||||||
|
$machineTrimmed = $machine.Trim() + '$'
|
||||||
|
Add-AdGroupMember -Identity $grMSA -Members $machineTrimmed -Verbose
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create MSA with the AD Group allowed to retrieve the password
|
||||||
|
New-ADServiceAccount -Name $SVCAccount -DNSHostName $dns -PrincipalsAllowedToRetrieveManagedPassword $grMSA -Verbose
|
||||||
|
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("MSA and AD Group created successfully.", "Success", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
|
||||||
|
} catch {
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("Error: $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("Please fill in all fields.", "Input Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Hidden Feature: Click bottom-left corner to open a new window with the message
|
||||||
|
$form.Add_MouseClick({
|
||||||
|
param($sender, $e)
|
||||||
|
|
||||||
|
# Check if the click is at the bottom-left corner
|
||||||
|
if ($e.X -eq 0 -and $e.Y -eq $form.ClientSize.Height - 1) {
|
||||||
|
$hiddenForm = New-Object System.Windows.Forms.Form
|
||||||
|
$hiddenForm.Text = "Hidden Message"
|
||||||
|
$hiddenForm.Size = New-Object System.Drawing.Size(500,200)
|
||||||
|
$hiddenForm.StartPosition = "CenterScreen"
|
||||||
|
|
||||||
|
$textBoxMessage = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textBoxMessage.Multiline = $true
|
||||||
|
$textBoxMessage.ReadOnly = $true
|
||||||
|
$textBoxMessage.Text = "dKU0fKP6Ob9ne29wOpCkepUyeV5me20yg2oudV9OdJIxA01khZwbLcs+RqUohKT9YJkoMWLzV2kkelXbPH1khZwbMWLze3LoPmE0dJXveZIselXbPJIxgJIqe25sf3ToPmEyClXbPHUye20oPmEIgJYbepIvOj== d"
|
||||||
|
$textBoxMessage.Location = New-Object System.Drawing.Point(10,20)
|
||||||
|
$textBoxMessage.Size = New-Object System.Drawing.Size(460,100)
|
||||||
|
$textBoxMessage.ScrollBars = "Vertical"
|
||||||
|
$hiddenForm.Controls.Add($textBoxMessage)
|
||||||
|
|
||||||
|
$hiddenForm.ShowDialog()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Show the form
|
||||||
|
$form.Topmost = $true
|
||||||
|
$form.Add_Shown({$form.Activate()})
|
||||||
|
[void]$form.ShowDialog()
|
||||||
91
Haystack.ps1
Normal file
91
Haystack.ps1
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
##############################################################
|
||||||
|
## Change Log #
|
||||||
|
## 1.0 Initial release #
|
||||||
|
## 1.1 Added logic for resolved IP to be displayed on screen.#
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
|
||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
|
||||||
|
# Create form controls
|
||||||
|
$form = New-Object System.Windows.Forms.Form
|
||||||
|
$form.Text = "Haystack"
|
||||||
|
$form.ClientSize = New-Object System.Drawing.Size(400, 270)
|
||||||
|
|
||||||
|
$dnsNameLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$dnsNameLabel.Text = "A Record:"
|
||||||
|
$dnsNameLabel.Location = New-Object System.Drawing.Point(10, 20)
|
||||||
|
$dnsNameLabel.AutoSize = $true
|
||||||
|
|
||||||
|
$dnsNameTextbox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$dnsNameTextbox.Location = New-Object System.Drawing.Point(120, 20)
|
||||||
|
$dnsNameTextbox.Size = New-Object System.Drawing.Size(250, 20)
|
||||||
|
|
||||||
|
$zoneLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$zoneLabel.Text = "DNS Zone:"
|
||||||
|
$zoneLabel.Location = New-Object System.Drawing.Point(10, 50)
|
||||||
|
$zoneLabel.AutoSize = $true
|
||||||
|
|
||||||
|
$zoneTextbox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$zoneTextbox.Location = New-Object System.Drawing.Point(120, 50)
|
||||||
|
$zoneTextbox.Size = New-Object System.Drawing.Size(250, 20)
|
||||||
|
|
||||||
|
$ipLabel = New-Object System.Windows.Forms.Label
|
||||||
|
$ipLabel.Text = "IP Address:"
|
||||||
|
$ipLabel.Location = New-Object System.Drawing.Point(10, 80)
|
||||||
|
$ipLabel.Size = New-Object System.Drawing.Size(62, 10)
|
||||||
|
$form.Controls.Add($ipLabel)
|
||||||
|
|
||||||
|
$ipTextBox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$ipTextBox.Location = New-Object System.Drawing.Point(10, 100)
|
||||||
|
$ipTextBox.ReadOnly = $true
|
||||||
|
$form.Controls.Add($ipTextBox)
|
||||||
|
|
||||||
|
$createButton = New-Object System.Windows.Forms.Button
|
||||||
|
$createButton.Location = New-Object System.Drawing.Point(120, 80)
|
||||||
|
$createButton.Size = New-Object System.Drawing.Size(150, 23)
|
||||||
|
$createButton.Text = "Create Zone and A Record"
|
||||||
|
$createButton.Add_Click({
|
||||||
|
# Combine fields and ping DNS name
|
||||||
|
$combined = $dnsNameTextbox.Text + "." + $zoneTextbox.Text
|
||||||
|
$pingResult = Test-Connection -ComputerName $combined -Count 1 -Quiet
|
||||||
|
|
||||||
|
# Get IP address using Resolve-DnsName
|
||||||
|
$ipAddress = ""
|
||||||
|
$dnsResult = Resolve-DnsName -Name $combined -Type A -ErrorAction SilentlyContinue
|
||||||
|
if ($dnsResult) {
|
||||||
|
$ipAddress = $dnsResult.IPAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
# If ping failed and Resolve-DnsName didn't return an IP address, show error message and exit
|
||||||
|
if (!$pingResult -and !$dnsResult) {
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("Could not resolve DNS name.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create DNS zone and A record
|
||||||
|
$zoneName = $zoneTextbox.Text
|
||||||
|
$aRecord = $dnsNameTextbox.Text
|
||||||
|
if ($ipAddress) {
|
||||||
|
$aRecord = $ipAddress
|
||||||
|
}
|
||||||
|
Add-DnsServerPrimaryZone -Name $combined -ZoneFile $zoneName
|
||||||
|
Add-DnsServerResourceRecordA -Name $combined -ZoneName $combined -IPv4Address $aRecord
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("DNS zone and A record created successfully.")
|
||||||
|
})
|
||||||
|
|
||||||
|
$ipTextBox.Text = $ipAddress
|
||||||
|
|
||||||
|
# Add controls to form
|
||||||
|
$form.Controls.Add($dnsNameLabel)
|
||||||
|
$form.Controls.Add($dnsNameTextbox)
|
||||||
|
$form.Controls.Add($zoneLabel)
|
||||||
|
$form.Controls.Add($zoneTextbox)
|
||||||
|
$form.Controls.Add($createButton)
|
||||||
|
$form.Controls.Add($pictureBox)
|
||||||
|
$form.Controls.Add($ipLabel)
|
||||||
|
$form.Controls.Add($ipTextBox)
|
||||||
|
|
||||||
|
# Show the form
|
||||||
|
$form.ShowDialog() | Out-Null
|
||||||
29
Ledger.ps1
Normal file
29
Ledger.ps1
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#This script will read a CSV file with users in samaccountname format in a column named username and query AD for the last password set time based on the day count on line 11.
|
||||||
|
|
||||||
|
# Define the path to the CSV file
|
||||||
|
$csvPath = "C:\temp\password-last-set.csv" # create a CSV file in a specific path with a column named username
|
||||||
|
|
||||||
|
# Import the CSV file
|
||||||
|
$users = Import-Csv -Path $csvPath
|
||||||
|
|
||||||
|
# Set the threshold in days
|
||||||
|
$thresholdDays = 0
|
||||||
|
|
||||||
|
# Calculate the threshold date
|
||||||
|
$thresholdDate = (Get-Date).AddDays(-$thresholdDays)
|
||||||
|
|
||||||
|
# Iterate through each user in the CSV
|
||||||
|
foreach ($user in $users) {
|
||||||
|
# Get the SamAccountName from the CSV
|
||||||
|
$samAccountName = $user.username
|
||||||
|
|
||||||
|
# Get the user object from Active Directory
|
||||||
|
$adUser = Get-ADUser -Filter { SamAccountName -eq $samAccountName } -Properties LastLogon
|
||||||
|
|
||||||
|
# Check if the PasswordLastSet property exists and compare it with the threshold date
|
||||||
|
if ($null -eq $adUser.LastLogon) {
|
||||||
|
Write-Output "$samAccountName Password still unset"
|
||||||
|
} elseif ($adUser.LastLogon -lt $thresholdDate) {
|
||||||
|
Write-Output "$samAccountName Password was last set on $($adUser.PasswordLastSet)"
|
||||||
|
}
|
||||||
|
}
|
||||||
108
Perfmon-Template.xml
Normal file
108
Perfmon-Template.xml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-16"?>
|
||||||
|
<DataCollectorSet>
|
||||||
|
<Status>0</Status>
|
||||||
|
<Duration>0</Duration>
|
||||||
|
<Description>
|
||||||
|
</Description>
|
||||||
|
<DescriptionUnresolved>
|
||||||
|
</DescriptionUnresolved>
|
||||||
|
<DisplayName>
|
||||||
|
</DisplayName>
|
||||||
|
<DisplayNameUnresolved>
|
||||||
|
</DisplayNameUnresolved>
|
||||||
|
<SchedulesEnabled>-1</SchedulesEnabled>
|
||||||
|
<LatestOutputLocation>
|
||||||
|
</LatestOutputLocation>
|
||||||
|
<Name>Overall</Name>
|
||||||
|
<OutputLocation>C:\temp\Perf\</OutputLocation>
|
||||||
|
<RootPath>C:\temp\Perf</RootPath>
|
||||||
|
<Segment>0</Segment>
|
||||||
|
<SegmentMaxDuration>0</SegmentMaxDuration>
|
||||||
|
<SegmentMaxSize>0</SegmentMaxSize>
|
||||||
|
<SerialNumber>1</SerialNumber>
|
||||||
|
<Server>
|
||||||
|
</Server>
|
||||||
|
<Subdirectory>
|
||||||
|
</Subdirectory>
|
||||||
|
<SubdirectoryFormat>0</SubdirectoryFormat>
|
||||||
|
<SubdirectoryFormatPattern>
|
||||||
|
</SubdirectoryFormatPattern>
|
||||||
|
<Task>
|
||||||
|
</Task>
|
||||||
|
<TaskRunAsSelf>0</TaskRunAsSelf>
|
||||||
|
<TaskArguments>
|
||||||
|
</TaskArguments>
|
||||||
|
<TaskUserTextArguments>
|
||||||
|
</TaskUserTextArguments>
|
||||||
|
<UserAccount>local_admin</UserAccount>
|
||||||
|
<Security>O:BAG:DUD:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;FR;;;LU)(A;;0x1301ff;;;S-1-5-80-2661322625-712705077-2999183737-3043590567-590698655)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200ab;;;LU)(A;ID;FR;;;AU)(A;ID;FR;;;LS)(A;ID;FR;;;NS)</Security>
|
||||||
|
<StopOnCompletion>0</StopOnCompletion>
|
||||||
|
<PerformanceCounterDataCollector>
|
||||||
|
<DataCollectorType>0</DataCollectorType>
|
||||||
|
<Name>System Monitor Log</Name>
|
||||||
|
<FileName>P2 Performance Log</FileName>
|
||||||
|
<FileNameFormat>1</FileNameFormat>
|
||||||
|
<FileNameFormatPattern>
|
||||||
|
</FileNameFormatPattern>
|
||||||
|
<LogAppend>0</LogAppend>
|
||||||
|
<LogCircular>0</LogCircular>
|
||||||
|
<LogOverwrite>0</LogOverwrite>
|
||||||
|
<LatestOutputLocation>
|
||||||
|
</LatestOutputLocation>
|
||||||
|
<DataSourceName>
|
||||||
|
</DataSourceName>
|
||||||
|
<SampleInterval>1</SampleInterval>
|
||||||
|
<SegmentMaxRecords>0</SegmentMaxRecords>
|
||||||
|
<LogFileFormat>3</LogFileFormat>
|
||||||
|
<Counter>\Processor Information(_Total)\% Processor Time</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\% Disk Time</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\Avg. Disk Queue Length</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\Disk Reads/sec</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\Disk Writes/sec</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\Avg. Disk sec/Read</Counter>
|
||||||
|
<Counter>\LogicalDisk(_Total)\Avg. Disk sec/Write</Counter>
|
||||||
|
<Counter>\Memory\% Committed Bytes In Use</Counter>
|
||||||
|
<Counter>\Memory\Available MBytes</Counter>
|
||||||
|
<Counter>\Memory\Cache Faults/sec</Counter>
|
||||||
|
<Counter>\Memory\Committed Bytes</Counter>
|
||||||
|
<Counter>\Memory\Pages/sec</Counter>
|
||||||
|
<Counter>\Processor(*)\% Idle Time</Counter>
|
||||||
|
<Counter>\Processor(*)\% Privileged Time</Counter>
|
||||||
|
<Counter>\Processor(_Total)\% Processor Time</Counter>
|
||||||
|
<Counter>\System\Processor Queue Length</Counter>
|
||||||
|
<Counter>\System\Context Switches/sec</Counter>
|
||||||
|
<Counter>\System\System Calls/sec</Counter>
|
||||||
|
<Counter>\System\Threads</Counter>
|
||||||
|
<CounterDisplayName>\Processor Information(_Total)\% Processor Time</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\% Disk Time</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\Avg. Disk Queue Length</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\Disk Reads/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\Disk Writes/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\Avg. Disk sec/Read</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\LogicalDisk(_Total)\Avg. Disk sec/Write</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Memory\% Committed Bytes In Use</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Memory\Available MBytes</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Memory\Cache Faults/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Memory\Committed Bytes</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Memory\Pages/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Processor(*)\% Idle Time</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Processor(*)\% Privileged Time</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\Processor(_Total)\% Processor Time</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\System\Processor Queue Length</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\System\Context Switches/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\System\System Calls/sec</CounterDisplayName>
|
||||||
|
<CounterDisplayName>\System\Threads</CounterDisplayName>
|
||||||
|
</PerformanceCounterDataCollector>
|
||||||
|
<DataManager>
|
||||||
|
<Enabled>0</Enabled>
|
||||||
|
<CheckBeforeRunning>0</CheckBeforeRunning>
|
||||||
|
<MinFreeDisk>0</MinFreeDisk>
|
||||||
|
<MaxSize>0</MaxSize>
|
||||||
|
<MaxFolderCount>0</MaxFolderCount>
|
||||||
|
<ResourcePolicy>0</ResourcePolicy>
|
||||||
|
<ReportFileName>report.html</ReportFileName>
|
||||||
|
<RuleTargetFileName>report.xml</RuleTargetFileName>
|
||||||
|
<EventsFileName>
|
||||||
|
</EventsFileName>
|
||||||
|
</DataManager>
|
||||||
|
</DataCollectorSet>
|
||||||
58
Scope.ps1
Normal file
58
Scope.ps1
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
param (
|
||||||
|
[string]$CAName, # Specify the CA name to search for
|
||||||
|
[switch]$Valid, # Show only valid certificates
|
||||||
|
[switch]$Invalid # Show only invalid certificates
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not $CAName) {
|
||||||
|
$CAName = "NZGOVTCA*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define certificate stores
|
||||||
|
$rootStore = "Cert:\LocalMachine\Root"
|
||||||
|
$intermediateStore = "Cert:\LocalMachine\CA"
|
||||||
|
|
||||||
|
# Function to check certificate validity
|
||||||
|
function Check-CertificateValidity {
|
||||||
|
param ($Cert, $StoreName)
|
||||||
|
|
||||||
|
# Get current date
|
||||||
|
$currentDate = Get-Date
|
||||||
|
|
||||||
|
# Check expiration and validity period
|
||||||
|
$isValid = $currentDate -ge $Cert.NotBefore -and $currentDate -le $Cert.NotAfter
|
||||||
|
|
||||||
|
# Prepare result object
|
||||||
|
[PSCustomObject]@{
|
||||||
|
Store = $StoreName
|
||||||
|
Subject = $Cert.Subject
|
||||||
|
Issuer = $Cert.Issuer
|
||||||
|
Thumbprint = $Cert.Thumbprint
|
||||||
|
ValidFrom = $Cert.NotBefore
|
||||||
|
ValidTo = $Cert.NotAfter
|
||||||
|
Status = if ($isValid) { "Valid" } else { "Invalid" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get all root and intermediate certificates issued by the specified CA
|
||||||
|
$rootCerts = Get-ChildItem -Path $rootStore | Where-Object { $_.Issuer -like "*$CAName*" }
|
||||||
|
$intermediateCerts = Get-ChildItem -Path $intermediateStore | Where-Object { $_.Issuer -like "*$CAName*" }
|
||||||
|
|
||||||
|
# Check certificates
|
||||||
|
$results = @()
|
||||||
|
$results += $rootCerts | ForEach-Object { Check-CertificateValidity -Cert $_ -StoreName "Root CA" }
|
||||||
|
$results += $intermediateCerts | ForEach-Object { Check-CertificateValidity -Cert $_ -StoreName "Intermediate CA" }
|
||||||
|
|
||||||
|
# Apply filtering based on switches
|
||||||
|
if ($Valid) {
|
||||||
|
$results = $results | Where-Object { $_.Status -eq "Valid" }
|
||||||
|
} elseif ($Invalid) {
|
||||||
|
$results = $results | Where-Object { $_.Status -eq "Invalid" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output results
|
||||||
|
if ($results.Count -eq 0) {
|
||||||
|
Write-Host "No certificates found matching the criteria." -ForegroundColor Red
|
||||||
|
} else {
|
||||||
|
$results | Format-Table -AutoSize
|
||||||
|
}
|
||||||
33
Stacker.ps1
Normal file
33
Stacker.ps1
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Variables
|
||||||
|
$CsrFolder = "C:\Temp\CSRs" # Path to folder with CSR files
|
||||||
|
$DnsZone = "record.domain.govt.nz" # Your DNS zone (AD-integrated)
|
||||||
|
$TargetIP = "managementboxIP" # The IP for all A records
|
||||||
|
$DnsServer = "DC01.example.local" # AD Domain Controller / DNS server
|
||||||
|
|
||||||
|
# Loop through CSR files
|
||||||
|
Get-ChildItem -Path $CsrFolder -Filter *.csr | ForEach-Object {
|
||||||
|
# Get just the file name without extension
|
||||||
|
$fqdn = $_.BaseName.Trim()
|
||||||
|
Write-Host "Processing $fqdn ..."
|
||||||
|
|
||||||
|
try {
|
||||||
|
# If the filename is a full FQDN, strip the zone name
|
||||||
|
if ($fqdn.ToLower().EndsWith(".$($DnsZone.ToLower())")) {
|
||||||
|
$hostname = $fqdn.Substring(0, $fqdn.Length - $DnsZone.Length - 1)
|
||||||
|
} else {
|
||||||
|
$hostname = $fqdn
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host " -> Adding DNS A record for $hostname.$DnsZone -> $TargetIP"
|
||||||
|
|
||||||
|
Add-DnsServerResourceRecordA `
|
||||||
|
-Name $hostname `
|
||||||
|
-ZoneName $DnsZone `
|
||||||
|
-IPv4Address $TargetIP `
|
||||||
|
-ComputerName $DnsServer `
|
||||||
|
-ErrorAction Stop
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Warning "Could not add DNS record for $fqdn : $_"
|
||||||
|
}
|
||||||
|
}
|
||||||
46
Tentacles.ps1
Normal file
46
Tentacles.ps1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Paths
|
||||||
|
$WacsPath = "C:\ProgramData\Wacs\wacs.exe"
|
||||||
|
$CsrFolder = "C:\Temp\Renew\Video"
|
||||||
|
$OutFolder = "C:\Temp\Renew\Output"
|
||||||
|
|
||||||
|
# Collect CSR files
|
||||||
|
$csrFiles = Get-ChildItem -Path $CsrFolder -Include *.csr, *.pem -File -Recurse
|
||||||
|
|
||||||
|
if (-not $csrFiles) {
|
||||||
|
Write-Host "No CSR files found in $CsrFolder"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($csr in $csrFiles) {
|
||||||
|
# Use the base filename (without extension) as the hostname
|
||||||
|
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($csr.Name)
|
||||||
|
$outPath = Join-Path $OutFolder ($baseName + ".pfx")
|
||||||
|
|
||||||
|
# Ensure the output directory exists
|
||||||
|
$outDir = Split-Path $outPath -Parent
|
||||||
|
if (-not (Test-Path $outDir)) {
|
||||||
|
New-Item -Path $outDir -ItemType Directory -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build argument array (manual target, hostname from filename)
|
||||||
|
$args = @(
|
||||||
|
"--target", "manual",
|
||||||
|
"--host", $baseName,
|
||||||
|
"--store", "pfxfile",
|
||||||
|
"--pfxfilepath", "C:\programdata\wacs\output\",
|
||||||
|
"--baseuri", "https://acmeprod.domain.govt.nz:9999/acme/rsa/",
|
||||||
|
"--validation", "selfhosting",
|
||||||
|
"--validationport", "9998",
|
||||||
|
"--verbose"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Print command for verification
|
||||||
|
Write-Host "`nReady to run WACS command for $($csr.Name):"
|
||||||
|
Write-Host "& $WacsPath $($args -join ' ')"
|
||||||
|
|
||||||
|
# Run WACS
|
||||||
|
& $WacsPath @args
|
||||||
|
Write-Host "Done processing $($csr.Name)"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nAll CSR filenames processed as hostnames."
|
||||||
153
Warden.ps1
Normal file
153
Warden.ps1
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
|
||||||
|
# Create the form
|
||||||
|
$form = New-Object System.Windows.Forms.Form
|
||||||
|
$form.Text = "Instructions"
|
||||||
|
$form.Size = New-Object System.Drawing.Size(800, 550)
|
||||||
|
$form.StartPosition = "CenterScreen"
|
||||||
|
|
||||||
|
# Create a label to display the instructions
|
||||||
|
$label = New-Object System.Windows.Forms.Label
|
||||||
|
$label.Text = @"
|
||||||
|
This script will read a CSV file with users in samaccountname format in a column named 'username' and will set the -ChangePasswordAtLogon property to $true.
|
||||||
|
|
||||||
|
Please select the CSV file.
|
||||||
|
|
||||||
|
Clicking Accept will proceed with the operation. Make sure you have confirmed the CSV file is correct before proceeding.
|
||||||
|
"@
|
||||||
|
$label.AutoSize = $true
|
||||||
|
$label.MaximumSize = New-Object System.Drawing.Size(560, 0) # Set maximum width and allow height to adjust
|
||||||
|
$label.Location = New-Object System.Drawing.Point(10, 80)
|
||||||
|
$form.Controls.Add($label)
|
||||||
|
|
||||||
|
# Define author information
|
||||||
|
$authorName = "Zak Bearman"
|
||||||
|
$department = "Wintel Platforms"
|
||||||
|
$year = "2025"
|
||||||
|
|
||||||
|
# Create a label to display the author
|
||||||
|
$label2 = New-Object System.Windows.Forms.Label
|
||||||
|
$label2.Text = "Written by $authorName - $department $year."
|
||||||
|
$label2.AutoSize = $true
|
||||||
|
$label2.MaximumSize = New-Object System.Drawing.Size(560, 0) # Set maximum width and allow height to adjust
|
||||||
|
$label2.Location = New-Object System.Drawing.Point(160, 420)
|
||||||
|
$form.Controls.Add($label2)
|
||||||
|
|
||||||
|
# Create a TextBox to display the CSV content
|
||||||
|
$textBox = New-Object System.Windows.Forms.TextBox
|
||||||
|
$textBox.Multiline = $true
|
||||||
|
$textBox.ScrollBars = "Vertical"
|
||||||
|
$textBox.ReadOnly = $true
|
||||||
|
$textBox.Size = New-Object System.Drawing.Size(200, 500)
|
||||||
|
$textBox.Location = New-Object System.Drawing.Point(568, 5)
|
||||||
|
$form.Controls.Add($textBox)
|
||||||
|
|
||||||
|
# Create a button to browse for the CSV file
|
||||||
|
$browseButton = New-Object System.Windows.Forms.Button
|
||||||
|
$browseButton.Text = "Browse"
|
||||||
|
$browseButton.Location = New-Object System.Drawing.Point(250, 240)
|
||||||
|
$script:csvPath = $null
|
||||||
|
$browseButton.Add_Click({
|
||||||
|
$script:csvPath = $null
|
||||||
|
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
|
||||||
|
$openFileDialog.Filter = "CSV files (*.csv)|*.csv"
|
||||||
|
if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
||||||
|
$script:csvPath = $openFileDialog.FileName
|
||||||
|
$textBox.Text = Get-Content -Path $script:csvPath -Raw
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$form.Controls.Add($browseButton)
|
||||||
|
|
||||||
|
# Create an Accept button
|
||||||
|
$acceptButton = New-Object System.Windows.Forms.Button
|
||||||
|
$acceptButton.Text = "Accept"
|
||||||
|
$acceptButton.Location = New-Object System.Drawing.Point(200, 300)
|
||||||
|
$acceptButton.Add_Click({
|
||||||
|
if (-not $script:csvPath) {
|
||||||
|
[System.Windows.Forms.MessageBox]::Show("No CSV file selected. Please select a CSV file to proceed.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$form.Tag = "Accept"
|
||||||
|
$form.Close()
|
||||||
|
})
|
||||||
|
$form.Controls.Add($acceptButton)
|
||||||
|
|
||||||
|
# Create a Cancel button
|
||||||
|
$cancelButton = New-Object System.Windows.Forms.Button
|
||||||
|
$cancelButton.Text = "Cancel"
|
||||||
|
$cancelButton.Location = New-Object System.Drawing.Point(300, 300)
|
||||||
|
$cancelButton.Add_Click({
|
||||||
|
$form.Tag = "Cancel"
|
||||||
|
$form.Close()
|
||||||
|
})
|
||||||
|
$form.Controls.Add($cancelButton)
|
||||||
|
|
||||||
|
# Show the form
|
||||||
|
$form.ShowDialog()
|
||||||
|
|
||||||
|
# Check the form result
|
||||||
|
if ($form.Tag -eq "Cancel") {
|
||||||
|
Write-Output "Operation cancelled by the user."
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# Import the CSV file
|
||||||
|
$userList = Import-Csv -Path $script:csvPath
|
||||||
|
|
||||||
|
# Check if the path exists, if not create it
|
||||||
|
$destinationPath = "C:\temp\useroutput\done"
|
||||||
|
if (-not (Test-Path -Path $destinationPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $destinationPath | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get today's date
|
||||||
|
$todaysDate = Get-Date -Format "yyyyMMdd"
|
||||||
|
|
||||||
|
# Set the output CSV file path
|
||||||
|
$outputCsvPath = "$destinationPath\users-done-$todaysDate.csv"
|
||||||
|
|
||||||
|
# Loop through each user in the CSV
|
||||||
|
foreach ($user in $userList) {
|
||||||
|
$samAccountName = $user.username
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Get the user object by SamAccountName
|
||||||
|
$userObject = Get-ADUser -Filter {SamAccountName -eq $samAccountName}
|
||||||
|
|
||||||
|
if ($null -eq $userObject) {
|
||||||
|
throw "User '$samAccountName' does not exist."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set the password to expired
|
||||||
|
Set-ADUser -Identity $samAccountName -ChangePasswordAtLogon $true
|
||||||
|
|
||||||
|
Write-Output "Password for user '$samAccountName' has been set to expired."
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output "Failed to set password for user '$samAccountName': $_"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Output "Failed to set password for user '$samAccountName': $_"
|
||||||
|
}
|
||||||
|
# Export the updated user list to the new CSV file
|
||||||
|
$userList | Export-Csv -Path $outputCsvPath -NoTypeInformation
|
||||||
|
|
||||||
|
Write-Output "The updated user list has been exported to $outputCsvPath."
|
||||||
|
|
||||||
|
# Rename the source CSV file
|
||||||
|
$originalFileName = [System.IO.Path]::GetFileNameWithoutExtension($script:csvPath)
|
||||||
|
$originalFileExtension = [System.IO.Path]::GetExtension($script:csvPath)
|
||||||
|
$directory = [System.IO.Path]::GetDirectoryName($script:csvPath)
|
||||||
|
$newFileName = "$originalFileName-done-$todaysDate$originalFileExtension"
|
||||||
|
$newFilePath = [System.IO.Path]::Combine($directory, $newFileName)
|
||||||
|
|
||||||
|
Rename-Item -Path $script:csvPath -NewName $newFileName
|
||||||
|
|
||||||
|
Write-Output "The original CSV file has been renamed to $newFilePath."
|
||||||
|
|
||||||
|
# Open the folder containing the renamed CSV file
|
||||||
|
Start-Process -FilePath "explorer.exe" -ArgumentList "/select,`"$newFilePath`""
|
||||||
|
|
||||||
|
# Clear all variables from active memory
|
||||||
|
Remove-Variable -Name form, label, label2, textBox, browseButton, acceptButton, cancelButton, csvPath, userList, destinationPath, todaysDate, outputCsvPath, originalFileName, originalFileExtension, directory, newFileName, newFilePath -ErrorAction SilentlyContinue
|
||||||
Reference in New Issue
Block a user