-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWirespeed-ADSync.ps1
More file actions
214 lines (192 loc) · 9.05 KB
/
Wirespeed-ADSync.ps1
File metadata and controls
214 lines (192 loc) · 9.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# Wirespeed-ADSync.ps1
param (
[switch]$Install,
[string]$Url
)
# Define the default API URL at the top
$ApiUrl = "http://localhost/api/on-prem-sync"
# If install mode is specified, update the script with the new URL and schedule it
if ($Install) {
# Ensure URL is provided when installing
if (-not $Url) {
Write-Host "Error: The -Url parameter is required when using -Install."
exit 1
}
# Define paths
$scriptPath = $PSCommandPath
$newScriptPath = "$PSScriptRoot\Wirespeed-ADSync-Configured.ps1"
# Read the original script content
$scriptContent = Get-Content $scriptPath -Raw
# Replace the API URL in the script
$updatedContent = $scriptContent -replace '\$ApiUrl = "http://localhost/api/on-prem-sync"', "\$ApiUrl = `"$Url`""
# Write the updated script to a new file
Set-Content -Path $newScriptPath -Value $updatedContent -Force
Write-Host "Updated script with API URL: $Url and saved as $newScriptPath"
# Define the scheduled task details
$taskName = "Wirespeed-ADSyncHourly"
$taskDescription = "Hourly sync of AD computers and users to SaaS API"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1) -RepetitionDuration ([TimeSpan]::MaxValue)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$newScriptPath`""
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
# Register the scheduled task
try {
Register-ScheduledTask -TaskName $taskName -Description $taskDescription -Trigger $trigger -Action $action -Settings $settings -Force -ErrorAction Stop
Write-Host "Scheduled task '$taskName' created to run hourly starting now."
} catch {
Write-Host "Failed to create scheduled task. Error: $($_.Exception.Message)"
exit 1
}
# Exit after installation
exit 0
}
# Import the Active Directory module
Import-Module ActiveDirectory
# Function to get nested group memberships for an object (user or computer)
function Get-NestedGroupMemberships {
param (
[Parameter(Mandatory = $true)]
[string]$DistinguishedName
)
$groups = [System.Collections.Generic.HashSet[PSObject]]::new()
# Get direct group memberships with both DN and Name
$directGroups = Get-ADGroup -Filter "Members -eq '$DistinguishedName'" -Properties DistinguishedName, Name
foreach ($group in $directGroups) {
$groupInfo = [PSCustomObject]@{
DistinguishedName = $group.DistinguishedName
Name = $group.Name
}
if ($groups.Add($groupInfo)) {
# Recursively get nested groups
$nestedGroups = Get-NestedGroupMemberships -DistinguishedName $group.DistinguishedName
foreach ($nestedGroup in $nestedGroups) {
$groups.Add($nestedGroup) | Out-Null
}
}
}
return $groups
}
# Collect all computers with standard metadata and nested group memberships
$computers = Get-ADComputer -Filter * -Properties Name, OperatingSystem, OperatingSystemVersion, LastLogonDate, whenCreated, whenChanged, DistinguishedName |
ForEach-Object {
$nestedGroups = Get-NestedGroupMemberships -DistinguishedName $_.DistinguishedName
[PSCustomObject]@{
Name = $_.Name
OperatingSystem = $_.OperatingSystem
OperatingSystemVersion= $_.OperatingSystemVersion
LastLogonDate = $_.LastLogonDate
WhenCreated = $_.whenCreated
WhenChanged = $_.whenChanged
SID = $_.SID.Value
GroupMemberships = @($nestedGroups | Select-Object DistinguishedName, Name)
}
}
# Collect all users with all properties and nested group memberships
$users = Get-ADUser -Filter * -Properties * |
ForEach-Object {
$nestedGroups = Get-NestedGroupMemberships -DistinguishedName $_.DistinguishedName
# Expand Manager field to include DN, SamAccountName, and UPN
$managerInfo = $null
if ($_.Manager) {
try {
$manager = Get-ADUser -Identity $_.Manager -Properties SamAccountName, UserPrincipalName -ErrorAction Stop
$managerInfo = [PSCustomObject]@{
DistinguishedName = $manager.DistinguishedName
SamAccountName = $manager.SamAccountName
UserPrincipalName = $manager.UserPrincipalName
}
} catch {
Write-Host "Warning: Could not retrieve manager details for $($_.SamAccountName). Error: $($_.Exception.Message)"
$managerInfo = [PSCustomObject]@{
DistinguishedName = $_.Manager
SamAccountName = $null
UserPrincipalName = $null
}
}
}
# Create user object with all properties
[PSCustomObject]@{
DistinguishedName = $_.DistinguishedName
Enabled = $_.Enabled
GivenName = $_.GivenName
Name = $_.Name
ObjectClass = $_.ObjectClass
ObjectGUID = $_.ObjectGUID
SamAccountName = $_.SamAccountName
SID = $_.SID.Value
Surname = $_.Surname
UserPrincipalName = $_.UserPrincipalName
CN = $_.CN
DisplayName = $_.DisplayName
Initials = $_.Initials
Mail = $_.Mail
TelephoneNumber = $_.TelephoneNumber
Mobile = $_.Mobile
HomePhone = $_.HomePhone
IpPhone = $_.IpPhone
Fax = $_.Fax
Pager = $_.Pager
OtherTelephone = $_.OtherTelephone
OtherMobile = $_.OtherMobile
OtherHomePhone = $_.OtherHomePhone
OtherIpPhone = $_.OtherIpPhone
OtherFax = $_.OtherFax
OtherPager = $_.OtherPager
Department = $_.Department
Title = $_.Title
Company = $_.Company
Division = $_.Division
EmployeeID = $_.EmployeeID
EmployeeNumber = $_.EmployeeNumber
EmployeeType = $_.EmployeeType
Manager = $managerInfo
Office = $_.Office
StreetAddress = $_.StreetAddress
POBox = $_.POBox
City = $_.City
State = $_.State
PostalCode = $_.PostalCode
Country = $_.Country
CountryCode = $_.CountryCode
c = $_.c
AccountExpirationDate = $_.AccountExpirationDate
LastLogonDate = $_.LastLogonDate
LastLogon = $_.LastLogon
LastLogonTimestamp = $_.LastLogonTimestamp
whenCreated = $_.whenCreated
whenChanged = $_.whenChanged
PasswordLastSet = $_.PasswordLastSet
PasswordNeverExpires = $_.PasswordNeverExpires
LockedOut = $_.LockedOut
AccountLockoutTime = $_.AccountLockoutTime
MemberOf = $_.MemberOf
UserAccountControl = $_.UserAccountControl
PrimaryGroupID = $_.PrimaryGroupID
BadLogonCount = $_.BadLogonCount
BadPwdCount = $_.BadPwdCount
LogonCount = $_.LogonCount
Description = $_.Description
Info = $_.Info
ProfilePath = $_.ProfilePath
HomeDirectory = $_.HomeDirectory
HomeDrive = $_.HomeDrive
ScriptPath = $_.ScriptPath
ThumbnailPhoto = $_.ThumbnailPhoto
"msDS-UserPasswordExpiryTimeComputed" = $_."msDS-UserPasswordExpiryTimeComputed"
GroupMemberships = @($nestedGroups | Select-Object DistinguishedName, Name)
}
}
# Combine data into a single object and convert to JSON
$data = @{
Computers = $computers
Users = $users
} | ConvertTo-Json -Depth 10
# Output JSON to console
Write-Host "Collected AD Data in JSON format:"
Write-Host $data
# Attempt to send data to the API endpoint
try {
$response = Invoke-WebRequest -Uri $ApiUrl -Method Post -Body $data -ContentType "application/json" -UseBasicParsing -ErrorAction Stop
Write-Host "Data successfully sent to $ApiUrl. Status: $($response.StatusCode)"
} catch {
Write-Host "Failed to send data to $ApiUrl. Error: $($_.Exception.Message)"
}