Sync-YCLDAPUsers-v2.ps1 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. <#
  2. .NOTES
  3. Copyright (c) LLC Yandex Cloud. All rights reserved.
  4. THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
  5. .SYNOPSIS
  6. Creates and synchronize LDAP Groups and its users with Yandex Cloud Groups and Federated users.
  7. LDAP administrator can control YC Group membeship through LDAP group.
  8. If user been excluded from LDAP group, his federated account in YC will be excluded from YC Group during next sync.
  9. To successfully run source code user have to be organization.admin in Yandex Cloud and have user priveleges in LDAP Domain.
  10. .DESCRIPTION
  11. 1. The sample script creates YC Group if its does not exist.
  12. 2. After that checks users and creates them if accounts don't exist in specified federation
  13. 3. After groups and users been created - validates group membership based on LDAP group membersip.
  14. 4. Excludes or includes users based on LDAP group membersip.
  15. .PARAMETER Bootstrap
  16. Mandatory
  17. Runs script in Bootstrap mode. Bootstrap mode creates groups if it doesn't exist in cloud. Requires strong cloud naming convention in parameter GroupNames.
  18. Incompatible with Mapping and CSV parameters.
  19. .PARAMETER GroupNames
  20. Mandatory.
  21. Running only in Bootstrap mode.
  22. Array @() of LDAP group names. Group name must contains only latin characters and special character "-".
  23. All other characters such as white space, dot, underscore, etc are unsupported by YC Naming Convertion.
  24. .PARAMETER Mapping
  25. Mandatory
  26. Runs script in Mapping mode. Parameter maps LDAP groups to cloud. Requires CSV parameter.
  27. Incompatible with Bootstrap and GroupNames parameters.
  28. .PARAMETER CSV
  29. Mandatory.
  30. Parameter running only in Mapping mode. Specifies path to CSV file with groups mapping. CSV has to be in UTF8 encoding and comma-separated.
  31. CSV header Format:
  32. "DomainGroup","CloudGroup"
  33. "Domain Group 1","cloud-group-1"
  34. "Domain Group 2","cloud-group-2"
  35. .PARAMETER YCToken
  36. Mandatory.
  37. An IAM token is a unique sequence of characters issued to a user after authentication.
  38. The user needs this token for authorization in the Yandex Cloud API and access to resources.
  39. for example using yc cli:
  40. yc iam create-token
  41. .PARAMETER YCOrgID
  42. Mandatory.
  43. Yandex Cloud Organization ID.
  44. .PARAMETER FederationName
  45. Mandatory.
  46. Specifies Yandex Cloud Federation's name.
  47. .PARAMETER LoginType
  48. Setting user's attribute as login in Yandex Cloud federation. Valid values: UPN or Mail.
  49. .PARAMETER LogDirectory
  50. Specifies the directory where the log file should be generated.
  51. The default value is the current directory ($pwd).
  52. .EXAMPLE
  53. # Getting IAM token
  54. $env:YC_TOKEN = $(yc iam create-token)
  55. # Setting up organization ID
  56. $env:YCOrgID = "bpf..."
  57. # Synchronizing groups and users
  58. .\Sync-YCLDAPUsers.ps1 -Bootstrap -GroupNames @("group1","Group2") -YCToken $env:YC_TOKEN -YCOrgID $env:YCOrgID FederationName = "dev-federation" -LoginType UPN
  59. This command will create and sync groups group1 and Group2
  60. in specifien organization and federation and using UPN as login.
  61. .EXAMPLE
  62. $Params = @{
  63. Bootstrap
  64. GroupNames = @("group-allow","group-deny")
  65. YCToken = $env:YC_TOKEN
  66. YCOrgID = $env:YCOrgID
  67. FederationName = "dev-federation"
  68. LoginType = "Mail"
  69. }
  70. .\Sync-YCLDAPUsers.ps1 @Params
  71. This command will create and sync groups group1 and Group2
  72. in specific organization and federation and using UPN as login.
  73. .EXAMPLE
  74. # Getting IAM token
  75. $env:YC_TOKEN = $(yc iam create-token)
  76. # Setting up organization ID
  77. $env:YCOrgID = "bpf..."
  78. # Synchronizing groups and users
  79. .\Sync-YCLDAPUsers.ps1 -Mapping -CSV "C:\work\mygroups.csv" -YCToken $env:YC_TOKEN -YCOrgID $env:YCOrgID FederationName = "dev-federation" -LoginType UPN
  80. This command will sync groups matched in CSV file.
  81. in specific organization and federation and using UPN as login.
  82. .OUTPUTS
  83. System.IO.FileInfo
  84. #>
  85. param (
  86. [Parameter(Mandatory=$true)]
  87. [ValidateNotNullOrEmpty()]
  88. $GroupNames = @(),
  89. [Parameter(Mandatory=$true)]
  90. [ValidateNotNullOrEmpty()]
  91. [string]
  92. $YCToken = $env:YC_TOKEN,
  93. [Parameter(Mandatory=$true)]
  94. [ValidateNotNullOrEmpty()]
  95. [string]
  96. $YCOrgID = "bpfncbpfnadtqjhoacqi",
  97. [Parameter(Mandatory=$true)]
  98. [ValidateNotNullOrEmpty()]
  99. [string]
  100. $FederationName,
  101. [Parameter(Mandatory=$true)]
  102. [string]
  103. [ValidateNotNullOrEmpty()]
  104. [ValidateSet("Mail", "UPN")]
  105. $LoginType = "UPN",
  106. $LogDirectory = "C:\work"
  107. )
  108. #region helpers
  109. # API Endpoints
  110. $APIEndpoints =@{
  111. IAMGroups = "https://organization-manager.api.cloud.yandex.net/organization-manager/v1/groups"
  112. IAMFederations = "https://organization-manager.api.cloud.yandex.net/organization-manager/v1/saml/federations"
  113. IAMOrganizations = "https://organization-manager.api.cloud.yandex.net/organization-manager/v1/organizations"
  114. }
  115. function WriteLog
  116. {
  117. param([string]$message,
  118. [string]$filename,
  119. [switch]$NoDate,
  120. [switch]$skipWriteToFile,
  121. [ValidateSet("Info","Warning","Error")]
  122. [string]$EventType
  123. )
  124. if (!$NoDate)
  125. {
  126. $logString = "{0}: {1}: {2}" -f (Get-Date).ToString("dd.MM.yyyy hh:mm:ss"), $EventType.ToUpper(), $message
  127. }
  128. else
  129. {
  130. $logString = $message
  131. }
  132. switch ($EventType)
  133. {
  134. "Warning" { Write-Warning $logString }
  135. "Error" { Write-Host $logString -ForegroundColor Red }
  136. "Info" { Write-Host $logString }
  137. Default { Write-Host $logString }
  138. }
  139. if (!$skipWriteToFile)
  140. {
  141. $mtx = New-Object System.Threading.Mutex($false, "WriteLogMutex")
  142. [void]$mtx.WaitOne()
  143. $logString | Out-File -FilePath $("$($LogDirectory)\\{1}_{0}.log" -f (Get-Date).ToString("dd.MM.yyyy"), $filename) -Append
  144. [void]$mtx.ReleaseMutex()
  145. }
  146. }
  147. function Get-YCService {
  148. param (
  149. $token,
  150. $service_uri,
  151. $id,
  152. $method,
  153. $body
  154. )
  155. $Headers = @{
  156. Authorization="Bearer $token"
  157. pageSize = "1"
  158. }
  159. if($body) {
  160. $Params = @{
  161. Uri = $service_uri
  162. Method = $method
  163. Headers = $Headers
  164. Body = $body
  165. }
  166. }
  167. else {
  168. $Params = @{
  169. Uri = $service_uri
  170. Method = $method
  171. Headers = $Headers
  172. }
  173. }
  174. $Result = Invoke-RestMethod @Params
  175. return $Result
  176. }
  177. #endregion
  178. function Get-LDAPUsersInGroup {
  179. [CmdletBinding()]
  180. param (
  181. $GroupName
  182. )
  183. $Filter = "(&(objectClass=group)(cn=$GroupName))"
  184. $Searcher = New-Object DirectoryServices.DirectorySearcher
  185. $Searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($rootDSE.defaultNamingContext)")
  186. $Searcher.Filter = $Filter
  187. $Searcher.SearchScope = "Subtree" # Either: "Base", "OneLevel" or "Subtree"
  188. $Group = $Searcher.FindAll()
  189. #$GroupDN = $Group.Properties.distinguishedname
  190. $Filter="(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=$($Group.Properties.distinguishedname)))"
  191. $Searcher = New-Object DirectoryServices.DirectorySearcher
  192. $Searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($rootDSE.defaultNamingContext)")
  193. $Searcher.Filter = $Filter
  194. $Searcher.SearchScope = "Subtree" # Either: "Base", "OneLevel" or "Subtree"
  195. $Searcher.PropertiesToLoad.Add("userPrincipalName") > $Null
  196. $Searcher.PropertiesToLoad.Add("sAMAccountName") > $Null
  197. $Searcher.PropertiesToLoad.Add("displayName") > $Null
  198. $Searcher.PropertiesToLoad.Add("sn") > $Null
  199. $Searcher.PropertiesToLoad.Add("givenName") > $Null
  200. $Searcher.PropertiesToLoad.Add("mail") > $Null
  201. $Searcher.PropertiesToLoad.Add("telephoneNumber") > $Null
  202. $Searcher.PropertiesToLoad.Add("thumbnailPhoto") > $Null
  203. $UserList = $Searcher.FindAll()
  204. return $UserList
  205. }
  206. #region Groups operations
  207. function Get-YCIAMGroup {
  208. [CmdletBinding()]
  209. param (
  210. [ValidateNotNullOrEmpty()]
  211. $YCToken = $env:YC_TOKEN,
  212. [ValidateNotNullOrEmpty()]
  213. $YCOrgID = $env:YC_ORG,
  214. $Name,
  215. $Id
  216. )
  217. $Result = (Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)?organizationId=$YCOrgID" -method "GET").groups
  218. if($Name) {
  219. $Result = $Result | Where-Object {$_.name -eq $Name}
  220. }
  221. if($Id) {
  222. $Result = $Result | Where-Object {$_.id -eq $Id}
  223. }
  224. return $Result
  225. }
  226. function Create-YcIAMGroup {
  227. [CmdletBinding()]
  228. param (
  229. [ValidateNotNullOrEmpty()]
  230. $YCToken = $env:YC_TOKEN,
  231. [ValidateNotNullOrEmpty()]
  232. $YCOrgID = $env:YC_ORG,
  233. $Name,
  234. $Description
  235. )
  236. if($Description) {
  237. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)?organizationId=$YCOrgID&name=$Name&description=$Description" -method "POST"
  238. }
  239. else {
  240. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)?organizationId=$YCOrgID&name=$Name" -method "POST"
  241. }
  242. return $Result
  243. }
  244. function Delete-YcIAMGroup {
  245. [CmdletBinding()]
  246. param (
  247. [ValidateNotNullOrEmpty()]
  248. $YCToken = $env:YC_TOKEN,
  249. [ValidateNotNullOrEmpty()]
  250. $YCOrgID = $env:YC_ORG,
  251. $Name,
  252. $Id
  253. )
  254. if($Name -and !$Id) {
  255. $Id = (Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $Name).id
  256. }
  257. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)/$Id" -method "DELETE"
  258. return $Result
  259. }
  260. function Get-YcIAMGroupMember {
  261. [CmdletBinding()]
  262. param (
  263. [ValidateNotNullOrEmpty()]
  264. $YCToken = $env:YC_TOKEN,
  265. [ValidateNotNullOrEmpty()]
  266. $YCOrgID = $env:YC_ORG,
  267. $GroupName,
  268. $GroupId,
  269. $FederationID,
  270. $FederationName,
  271. # GetYcIAMUser
  272. $UserName
  273. )
  274. if($GroupName -and !$GroupId) {
  275. $GroupId = (Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName).id
  276. }
  277. $Ids = @()
  278. if($FederationName -and !$FederationID) {
  279. $Ids = (Get-YcOrgFederation -YCToken $YCToken -YCOrgID $YCOrgID -Name $FederationName).id
  280. }
  281. else {
  282. $Ids = $FederationID
  283. }
  284. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)/$GroupId`:listMembers" -method "GET"
  285. if($UserName) {
  286. $ID = (Get-YcOrgFederatedUser -YCToken $YCToken -YCOrgID $YCOrgID -FederationID $Ids -NameID $UserName).id
  287. if($Result.members -match $ID) {
  288. $Result = $Result.members -match $ID
  289. }
  290. else {
  291. $Result = $null
  292. }
  293. }
  294. if($Result) {
  295. return $Result
  296. }
  297. }
  298. #endregion
  299. #region Federations
  300. function Get-YcOrgFederation {
  301. [CmdletBinding()]
  302. param (
  303. [ValidateNotNullOrEmpty()]
  304. $YCToken = $env:YC_TOKEN,
  305. [ValidateNotNullOrEmpty()]
  306. $YCOrgID = $env:YC_ORG,
  307. $Name,
  308. $Id
  309. )
  310. $Result = (Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMFederations)?organizationId=$YCOrgID" -method "GET").federations
  311. if($Name) {
  312. $Result = $Result | Where-Object {$_.name -eq $Name}
  313. }
  314. if($Id) {
  315. $Result = $Result | Where-Object {$_.id -eq $Id}
  316. }
  317. return $Result
  318. }
  319. function Get-YcOrgFederatedUser {
  320. [CmdletBinding()]
  321. param (
  322. [ValidateNotNullOrEmpty()]
  323. $YCToken = $env:YC_TOKEN,
  324. [ValidateNotNullOrEmpty()]
  325. $YCOrgID = $env:YC_ORG,
  326. $FederationID,
  327. $FederationName,
  328. $NameID
  329. )
  330. # organization-manager.api.cloud.yandex.net/organization-manager/v1/saml/federations/{federationId}:listUserAccounts
  331. $Ids = @()
  332. if($FederationName -and !$FederationID) {
  333. $Ids = (Get-YcOrgFederation -YCToken $YCToken -YCOrgID $YCOrgID -Name $FederationName).id
  334. }
  335. else {
  336. $Ids = $FederationID
  337. }
  338. if(!$FederationName -and !$FederationID) {
  339. $Ids = (Get-YcOrgFederation -YCToken $YCToken -YCOrgID $YCOrgID).id
  340. }
  341. $Result = @()
  342. foreach($ID in $Ids) {
  343. #$Result +=
  344. $Result += Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMFederations)/$ID`:listUserAccounts?pageSize=1000" -method "GET"
  345. if($Result.nextPageToken) {
  346. $Result += Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMFederations)/$ID`:listUserAccounts?pageSize=1000?pageToken=$($Result.nextPageToken)" -method "GET"
  347. }
  348. $Result = $Result.userAccounts
  349. }
  350. if($NameID) {
  351. $tmp = @()
  352. foreach($UserId in $Result) {
  353. if($UserID.samlUserAccount -match $NameID) {
  354. $tmp += $UserID
  355. }
  356. }
  357. $Result = $tmp
  358. }
  359. return $Result
  360. }
  361. function Add-YcOrgFederatedUser {
  362. [CmdletBinding()]
  363. param (
  364. [ValidateNotNullOrEmpty()]
  365. $YCToken = $env:YC_TOKEN,
  366. [ValidateNotNullOrEmpty()]
  367. $YCOrgID = $env:YC_ORG,
  368. $FederationID,
  369. $FederationName,
  370. $NameIDs
  371. )
  372. # organization-manager.api.cloud.yandex.net/organization-manager/v1/saml/federations/{federationId}:listUserAccounts
  373. if($FederationName -and !$FederationID) {
  374. $FederationID = (Get-YcOrgFederation -YCToken $YCToken -YCOrgID $YCOrgID -Name $FederationName).id
  375. }
  376. if(!$FederationName -and !$FederationID) {
  377. throw "Federation Name or Federation ID must be specified."
  378. }
  379. $Result = Get-YCService -token $YCToken -service_uri "https://organization-manager.api.cloud.yandex.net/organization-manager/v1/saml/federations/$FederationID`:addUserAccounts?nameIds=$NameIDs" -method "POST"
  380. return $Result
  381. }
  382. function Delete-YcOrgFederatedUser {
  383. [CmdletBinding()]
  384. param (
  385. [ValidateNotNullOrEmpty()]
  386. $YCToken = $env:YC_TOKEN,
  387. [ValidateNotNullOrEmpty()]
  388. $YCOrgID = $env:YC_ORG,
  389. $Id,
  390. $Name,
  391. $FederationID,
  392. $FederationName
  393. )
  394. # organization-manager.api.cloud.yandex.net/organization-manager/v1/saml/federations/{federationId}:listUserAccounts
  395. if($FederationName -and !$FederationID) {
  396. $FederationID = (Get-YcOrgFederation -YCToken $YCToken -YCOrgID $YCOrgID -Name $FederationName).id
  397. }
  398. if(!$FederationName -and !$FederationID) {
  399. throw "Federation Name or Federation ID must be specified."
  400. }
  401. $OrgID = (Get-YcOrgFederation -Id $FederationID).organizationId
  402. if($Name -and !$Id){
  403. $Id = (Get-YcOrgFederatedUser -Name $Name -FederationID $FederationID).id
  404. }
  405. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMOrganizations)/$OrgID/users/$Id" -method "DELETE"
  406. return $Result
  407. }
  408. function Add-YCOrgFederatedUsersToGroup {
  409. [CmdletBinding()]
  410. param (
  411. [ValidateNotNullOrEmpty()]
  412. $YCToken = $env:YC_TOKEN,
  413. [ValidateNotNullOrEmpty()]
  414. $YCOrgID = $env:YC_ORG,
  415. [ValidateNotNullOrEmpty()]
  416. $GroupName,
  417. $GroupID,
  418. [Object[]]$FederatedUsers,
  419. [Object[]]$FederatedUserIDs,
  420. $FederationName
  421. )
  422. if($GroupName -and !$GroupId) {
  423. $GroupId = (Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName).id
  424. }
  425. $UsersToAdd = @()
  426. if($FederatedUsers -and !$FederatedUserIDs){
  427. foreach($FederatedUserName in $FederatedUsers) {
  428. $FederatedUserID = (Get-YcOrgFederatedUser -NameID $FederatedUserName -FederationName $FederationName).id
  429. $Object = "" | select @{n="action";e={"ADD"}},@{n="subjectId";e={"$FederatedUserID"}}
  430. $UsersToAdd += $Object
  431. }
  432. }
  433. else {
  434. foreach($FederatedUserID in $FederatedUserIDs) {
  435. $Object = "" | select @{n="action";e={"ADD"}},@{n="subjectId";e={"$FederatedUserID"}}
  436. $UsersToAdd += $Object
  437. }
  438. }
  439. $Deltas = [PSCustomObject]@{
  440. memberDeltas = $UsersToAdd
  441. } | ConvertTo-Json
  442. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)/$GroupID`:updateMembers" -method "POST" -Body $Deltas
  443. $Result
  444. }
  445. function Remove-YCOrgFederatedUsersFromGroup {
  446. [CmdletBinding()]
  447. param (
  448. [ValidateNotNullOrEmpty()]
  449. $YCToken = $env:YC_TOKEN,
  450. [ValidateNotNullOrEmpty()]
  451. $YCOrgID = $env:YC_ORG,
  452. [ValidateNotNullOrEmpty()]
  453. $GroupName,
  454. $GroupID,
  455. [Object[]]$FederatedUsers,
  456. [Object[]]$FederatedUserIDs,
  457. $FederationName
  458. )
  459. if($GroupName -and !$GroupId) {
  460. $GroupId = (Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName).id
  461. }
  462. $UsersToRemove = @()
  463. if($FederatedUsers -and !$FederatedUserIDs){
  464. foreach($FederatedUserName in $FederatedUsers) {
  465. $FederatedUserID = (Get-YcOrgFederatedUser -NameID $FederatedUserName -FederationName $FederationName).id
  466. $Object = "" | select @{n="action";e={"REMOVE"}},@{n="subjectId";e={"$FederatedUserID"}}
  467. $UsersToRemove += $Object
  468. }
  469. }
  470. else {
  471. foreach($FederatedUserID in $FederatedUserIDs) {
  472. $Object = "" | select @{n="action";e={"ADD"}},@{n="subjectId";e={"$FederatedUserID"}}
  473. $UsersToRemove += $Object
  474. }
  475. }
  476. $Deltas = [PSCustomObject]@{
  477. memberDeltas = $UsersToRemove
  478. } | ConvertTo-Json
  479. $Result = Get-YCService -token $YCToken -service_uri "$($APIEndpoints.IAMGroups)/$GroupID`:updateMembers" -method "POST" -Body $Deltas
  480. $Result
  481. }
  482. #endregion
  483. #region Main
  484. $filename = (Get-Date -f MMddyyyy_hh_mm).Tostring()+"_YCGroupSyncLog.log"
  485. $errorlog = (Get-Date -f MMddyyyy_hh_mm).Tostring()+"_YCGroupSyncErrorLog.log"
  486. if(!$LogDirectory) {
  487. $LogDirectory = (Get-Location).Path
  488. }
  489. WriteLog -message "Getting RootDSE" -EventType Info -filename $filename
  490. try {
  491. $rootDSE = [adsi]"LDAP://rootDSE"
  492. }
  493. catch {
  494. {
  495. 1: throw "Could not find RootDSE or [adsi] does not exist."
  496. WriteLog -message "Could not find RootDSE or [adsi] does not exist." -EventType Error -filename $filename
  497. WriteLog -message "Could not find RootDSE or [adsi] does not exist." -EventType Error -filename $errorlog
  498. }
  499. }
  500. foreach ($GroupName in $GroupNames){
  501. WriteLog -message "Processing group $GroupName" -EventType Info -filename $filename
  502. if($rootDSE) {
  503. WriteLog -message "Getting LDAP users in group $GroupName" -EventType Info -filename $filename
  504. $LDAPUsers = Get-LDAPUsersInGroup -GroupName $GroupName
  505. WriteLog -message "Getting YC Group $GroupName in Cloud Organization $YCOrgID" -EventType Info -filename $filename
  506. $YCGroup = Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName.ToLower()
  507. if(!$YCGroup) {
  508. WriteLog -message "YC Group $GroupName not found in Cloud Organization $YCOrgID" -EventType Info -filename $filename
  509. WriteLog -message "Creating YC Group $GroupName not found in Cloud Organization $YCOrgID" -EventType Info -filename $filename
  510. try {
  511. $outNull = Create-YcIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName.ToLower() -ErrorAction stop
  512. $YCGroup = Get-YCIAMGroup -YCToken $YCToken -YCOrgID $YCOrgID -Name $GroupName.ToLower()
  513. }
  514. catch {
  515. WriteLog -message "Could not create group $GroupName in Cloud Organization $YCOrgID. Please check YC Groups naming convention and try again." -EventType Error -filename $filename
  516. WriteLog -message "Could not create group $GroupName in Cloud Organization $YCOrgID. Please check YC Groups naming convention and try again." -EventType Error -filename $errorlog
  517. throw "Could not create group $GroupName in Cloud Organization $YCOrgID. Please check YC Groups naming convention and try again."
  518. }
  519. }
  520. else {
  521. WriteLog -message "Found YC Group group $($GroupName.ToLower())" -EventType Info -filename $filename
  522. }
  523. $UsersToAdd = @()
  524. foreach($LDAPUser in $LDAPUsers) {
  525. WriteLog -message "Processing user $($LDAPUser.Properties.userprincipalname)" -EventType Info -filename $filename
  526. if($LDAPUser.Properties.userprincipalname -ne $null -or $LDAPUser.Properties.mail -ne $null) {
  527. if($LoginType -eq "Mail") {
  528. if($LDAPUser.Properties.mail) {
  529. $username = $LDAPUser.Properties.mail.ToLower()
  530. WriteLog -message "Mail as login is selected. Login is: $username" -EventType Info -filename $filename
  531. }
  532. else {
  533. $DomainName = $rootDSE.ldapServiceName.ToString()
  534. $username = "$($LDAPUser.Properties.samaccountname)@$($DomainName.Substring(0, $DomainName.IndexOf(':')))"
  535. WriteLog -message "Mail as login is selected, but attribute Mail is empty. Using UPN for user: $username" -EventType Info -filename $filename
  536. }
  537. }
  538. if($LoginType -eq "UPN") {
  539. if($LDAPUser.Properties.userprincipalname) {
  540. $username = $LDAPUser.Properties.userprincipalname.ToLower()
  541. WriteLog -message "UPN as login is selected. Login is: $username" -EventType Info -filename $filename
  542. }
  543. else {
  544. $DomainName = $rootDSE.ldapServiceName.ToString()
  545. $username = "$($LDAPUser.Properties.samaccountname)@$($DomainName.Substring(0, $DomainName.IndexOf(':')))"
  546. WriteLog -message "UPN as login is selected, but attribute UserPrincipalName is empty. Login is: $username" -EventType Info -filename $filename
  547. }
  548. }
  549. WriteLog -message "Searching $username in federation $FederationName" -EventType Info -filename $filename
  550. $FederatedUser = Get-YcOrgFederatedUser -YCToken $YCToken -YCOrgID $YCOrgID -FederationName $FederationName -NameID $username
  551. if(!$FederatedUser) {
  552. WriteLog -message "User $username not found in federation $FederationName. Creating..." -EventType Info -filename $filename
  553. $outNull = Add-YcOrgFederatedUser -YCToken $YCToken -YCOrgID $YCOrgID -FederationName $FederationName -NameIDs @("$username")
  554. }
  555. WriteLog -message "Checking $username for membership in group $GroupName" -EventType Info -filename $filename
  556. $YCGroupMembership = Get-YcIAMGroupMember -YCToken $YCToken -YCOrgID $YCOrgID -GroupName $GroupName.ToLower() -UserName $username -FederationName $FederationName
  557. if(!$YCGroupMembership) {
  558. WriteLog -message "User $username added for membership in group $GroupName" -EventType Info -filename $filename
  559. $UsersToAdd += $username
  560. }
  561. }
  562. }
  563. if($UsersToAdd) {
  564. $outNull = Add-YCOrgFederatedUsersToGroup -YCToken $YCToken -YCOrgID $YCOrgID -GroupID $YCGroup.id -FederatedUsers $UsersToAdd -FederationName $FederationName
  565. WriteLog -message "Users $UsersToAdd has been added to group $($GroupName.ToLower())" -EventType Info -filename $filename
  566. }
  567. WriteLog -message "Validating group membership in group $($GroupName.ToLower())" -EventType Info -filename $filename
  568. $YCGroupMembers = Get-YcIAMGroupMember -YCToken $YCToken -YCOrgID $YCOrgID -GroupName $GroupName.ToLower()
  569. foreach($YCGroupMember in $YCGroupMembers.members) {
  570. $NameID = (Get-YcOrgFederatedUser -YCToken $YCToken -YCOrgID $YCOrgID -FederationName $FederationName | where {$_.id -eq $YCGroupMember.subjectId}).samlUserAccount.nameId
  571. if($NameID -and (!($LDAPUsers.Properties.userprincipalname -match $NameID) -or !($LDAPUsers.Properties.mail -match $NameID))) {
  572. WriteLog -message "User $NameID been excluded from LDAP group $GroupName excluding from YC Group $($GroupName.ToLower())" -EventType Info -filename $filename
  573. $outNull = Remove-YCOrgFederatedUsersFromGroup -YCToken $YCToken -YCOrgID $YCOrgID -GroupName $GroupName.ToLower() -FederatedUsers @("$NameID") -FederationName $FederationName
  574. WriteLog -message "User $NameID has been removed from group $($GroupName.ToLower())" -EventType Info -filename $filename
  575. }
  576. }
  577. }
  578. }
  579. #endregion