Guest User

PS-hybrid environment/devOps

a guest
Oct 28th, 2025
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 31.58 KB | Source Code | 0 0
  1. $DebugPreference = "Continue" #comment this line out when you don't want to enable the debugging output.
  2. #$VerbosePreference = "Continue"
  3. $ErrorActionPreference = "Continue"
  4.  
  5. $LogFolder = "$env:userprofile\desktop\logs" #log file location.
  6. $TranscriptLog = -join($LogFolder,"\transcript.log")
  7. Start-Transcript -Path $TranscriptLog -Force
  8. $csvPath = 'C:\Users\sa.ps\OneDrive - domain.com\Documents\ExternalContacts' #changeme - Location where the website is delivering the CVS files.  Only a directory path is needed, do not enter a full path to a specific CSV file.
  9.  
  10.  
  11.  
  12. function Format-CsvValue {
  13.     [CmdletBinding()]
  14.     param (
  15.         #Sets whether or not we want to format the provided string into 'title' (aka Proper) case when using named values.
  16.         #When isTitleCase = $true the function will take the input string ($sValue) and format it to proper(title) case and will also remove leading and trailing whitespaces.  Example; "JoHN SmITH" will return "John Smith" or "   JaNE " will return "Jane" (removed whitespaces and set to title case).
  17.         [Parameter(Mandatory = $false)]
  18.         [bool]
  19.         $isTitleCase = $false,
  20.         #The string value that's passed into the function to properly format.
  21.         #Example: Format-CsvValue -isTitleCase $true -sValue $mvar
  22.         #Example: To only remove whitespace from a string-> Format-CsvValue -sValue $myvar
  23.         [Parameter(Mandatory = $false)]  # was originally true
  24.         [string]
  25.         $sValue
  26.    
  27.     ) #=>Params
  28.  
  29.     begin {
  30.         #no variables or intitializations to declare.
  31.     } #=>begin
  32.  
  33.     process {
  34.         if ($isTitleCase) {
  35.             #isTitleCase is set to true so let's format it...
  36.             $rValue = $((Get-Culture).TextInfo.ToTitleCase($sValue.ToLower())).Trim() #trim leading/trailing whitespace AND convert to title case string format.
  37.         }
  38.         else {
  39.             #only whitespace trim is required, process that request.
  40.             $rValue = $sValue.Trim() #Remove leading/trailing whitespace.
  41.         }#=>if/isTitleCase
  42.     }#=>process
  43.  
  44.     end {
  45.         #return the value through the function.
  46.         $rValue
  47.     }
  48. } #=>Format-CsvValue
  49.  
  50.  
  51.  
  52. Function Write-CustomEventLog {
  53.     [CmdletBinding()]
  54.     param(
  55.         # What message to write to the event viewer.
  56.         [Parameter(Mandatory=$true)]
  57.         [string]
  58.         $message,
  59.         # Type
  60.         [Parameter(Mandatory=$true)]
  61.         [ValidateSet('Information','Warning','Error')]
  62.         [string]
  63.         $entryType
  64.     )
  65.  
  66.     Begin {
  67.         $eventSourceExists = [System.Diagnostics.EventLog]::SourceExists("Update-domainAD")
  68.         if(-not($eventSourceExists)) {
  69.             try {
  70.                 New-EventLog -LogName Application -Source 'Update-domainAD'
  71.             }
  72.             catch {
  73.                 Write-Debug 'Unable to create new application source.'
  74.             }
  75.         }#=>if not $eventSourceExists
  76.     }#=>Begin
  77.  
  78.     Process {
  79.         switch ($entryType) {
  80.             "Information" { [int]$EventID = 1000 }
  81.             "Warning" { [int]$EventID = 2000 }
  82.             "Error" { [int]$EventID = 3000}
  83.         }
  84.         Write-EventLog -LogName Application -Source 'Update-domainAD' -EntryType $entryType -EventId $EventID -Message $message
  85.     }
  86. }
  87.  
  88. #Import-Module ActiveDirectory
  89.  
  90. if (!($isScheduled)) {
  91.     Write-Debug "This is not a scheduled task so we can safely assume this is an initial read of a CSV file. Looking for all CSV files in $($csvPath) that are NOT readonly."
  92.     #since we are anticipating *dynamically* named CSV files let's find all CSV files we have yet to process.
  93.     $csvFiles = Get-ChildItem -Path $csvPath -Filter "NS*.csv" -Attributes !readonly+!directory
  94.     $csvCount = ($csvFiles | Measure-Object).Count
  95.     Write-Debug "Found $($csvCount) CSV files in $($csvPath) to process: `n`n `$csvFiles: $($csvFiles)"
  96.     if ($csvFiles) {
  97.         Write-Debug "Found unprocessed CSV files..."
  98.         foreach ($csvFile in $csvFiles) {
  99.             Write-Debug "Processing CSV file $($csvFile.FullName)"
  100.             try {
  101.                 $Users = Import-CSV $csvFile.FullName
  102.             }
  103.             catch {
  104.                
  105.                
  106.                 #We need to check if the csvFiles count is greater than 1. If it is, we can move to the next file. If it's not, we need to throw an error and exit this script.
  107.                 if ($csvCount -gt '1') {
  108.                     Write-CustomEventLog -message "Unable to import CSV file: $($csvFile.FullName). This is a fatal error for this csv file. Continuing to next file. Error message is: `n`n $($Error[0].Exception.Message)" -entryType "Warning"
  109.                     Write-Debug "Unable to import our CSV file: $($csvFile.FullName). This is a fatal error for this CSV file.  Continuing to next file. Error message is: $Error[0].Exception.Message"
  110.                     Continue
  111.                 } else {
  112.                     Write-CustomEventLog -message "Unable to import CSV file: $($csvFile.FullName). This is a fatal error for this csv file and this script. Exiting script. Error message is: `n`n $($Error[0].Exception.Message)" -entryType "Error"
  113.                     Write-Debug "Unable to import our CSV file: $($csvFile.FullName). This is a fatal error for this CSV file and this script. Exiting script. Error message is: $Error[0].Exception.Message"
  114.                     Throw $csvFile.FullName
  115.                 }
  116.                
  117.  
  118.             }#=> try $Users
  119.        
  120.             #imported our CSV file properly.  Let's process the file for new users...
  121.             ForEach ($User in $Users){
  122.                 #debugging purposes...
  123.                 Write-Debug "First Name: $($User.Firstname)"
  124.                 Write-Debug "Last Name : $($User.Lastname)"
  125.                 Write-Debug "StartDate : $($User.startdate)"
  126.                 #Write-Debug "Email : $($User.Email)"
  127.                 Write-Debug "Title : $($User.Title)"
  128.                 Write-Debug "Department :$($User.Department)"
  129.                 Write-Debug "CopyUser : $($User.copyUser)"
  130.                 Write-Debug "Mobile     :$($user.Mobile)"
  131.                 Write-Debug "Manager    :$($user.Manager)"
  132.                 Write-Debug "BusinessUnit :$($user.BusinessUnit)"
  133.                 Write-Debug "OfficeLocation : $($User.OfficeLocation)"
  134.                 Write-Debug "Country :$($User.Country)"
  135.  
  136.        
  137.                 #Let's properly format all the values in this *ROW* of the CSV. Trim() where necessary and change to Title Case where necessary - also create a new variable so we can use it later when creating the user in AD using the New-ADuser cmdlet.
  138.                 $FirstName = Format-CsvValue -isTitleCase $true -sValue $User.FirstName #trim and title case
  139.                 $LastName = Format-CsvValue -isTitleCase $true -sValue $User.LastName #trim and title case.
  140.                 #$Email = Format-CsvValue -sValue $User.Email #trim only.
  141.                 $StartDate = Format-CsvValue -sValue $User.startdate #trim only.
  142.                 $copyUser = $User.copyUser
  143.                 $Title = $User.Title
  144.                 $PreferredLanguage = $User.PreferredLanguage
  145.                 $EmployeeType = $User.EmployeeType
  146.                 $Department = $User.Department
  147.                 $Mobile = $User.Mobile
  148.                 $Manager = $User.Manager
  149.                 $BusinessUnit = $User.BusinessUnit
  150.                 $officeLocation = $User.OfficeLocation.split('(')[0]
  151.                 $Country = $User.Country
  152.                 #$EndDate = Format-CsvValue -sValue $User.enddate #trim only.
  153.                 #$Company = Format-CsvValue -sValue $User.company #trim only since company names are rather specific on how they're spelled out.
  154.                 if ($csvFile.Name -like "NS*") {
  155.                     #This csvFile that we're working on seems to be a New User request as defined by the "NU" in the CSV file name so we add more details.
  156.                     $copyUser = $User.copyUser #We need the fullname of the user we're copying from.
  157.                 }
  158.                 #=> End of CSV values.
  159.  
  160.                 #Let's build other necessary variables that we want to use as parameters for the New-ADuser cmdlet out of the information provided by the CSV file or other sources...
  161.                 $FullName = -join($($FirstName)," ",$($LastName)) #join $Firstname and $Lastname and a space to get FullName
  162.                 $SAM = -join($($FirstName.Replace(' ','')),'.',$($LastName.Replace(' ',''))) #this assumes that your SAM naming convention is first.LASTNAME and makes everything lowercase.
  163.                 if($SAM.Length -gt 20){$SAM = $SAM.Substring(0,20)}
  164.                 $DisplayName = -join($($FirstName),' ',$($LastName))
  165.                 $Username = (-join($FirstName,".",$LastName)).ToLower() #this assumes that your usernames have a naming convention of firstname.lastname and makes everything lowercase.
  166.                 $DNSroot = "@$((Get-ADDomain).dnsroot)"
  167.                 $UPN = -join($SAM,'@domain.com')
  168.                 $Email = -join($SAM,'@domain.com')
  169.                 $Title = $Title
  170.                 $Manager = $Manager
  171.                 $Company = "domain NV"
  172.                 $Password = (ConvertTo-SecureString -AsPlainText '#jiKlp@n2!' -Force)
  173.                 $oStartDate = $User.StartDate #This converts the CSV "startdate" field from a string to a datetime object so we can use it for comparison.
  174.                 #$oEndDate = [datetime]::ParseExact(($User.EndDate).Trim(), "dd/MM/yyyy", $null) #This conerts to CSV 'EndDate' field from a string to a datetime object which is required for the New-AdUser cmdlet 'AccountExpirationDate' parameter.
  175.                 $today=(get-date).ToString('yyyy-MM-dd')
  176.                
  177.  
  178.                 # This function can be called to send an mail in case of conflict in creating an account
  179.                 function Send-Mail{
  180.                     [CmdletBinding()]
  181.                     param ()
  182.                     $cred = Get-Credential (Get-Secret -Vault KeyVaultStore -Name DecoAutomate)
  183.                     $sendMbx = "[email protected]"
  184.                     $recMbx = "[email protected]"
  185.                     $body   = "User with SamAccountName '$SAM' already exist, this account will have to be created manually."
  186.                
  187.                     $mailProps = @{
  188.                            
  189.                         SMTPServer = "smtp.office365.com"
  190.                         From = $sendMbx
  191.                         To = $recMbx
  192.                         Cc = "[email protected]"
  193.                         Subject = "SamAccountName Conflict($SAM)"
  194.                         UseSSL = $true
  195.                         Port = 587
  196.                         Credential = $cred
  197.                     }
  198.                     Send-MailMessage @mailProps $body
  199.  
  200.  
  201.                 }
  202.                 function informsmith6 {
  203.                     [CmdletBinding()]
  204.                     param ()
  205.                     $cred = Get-Credential (Get-Secret -Vault KeyVaultStore -Name DecoAutomate)
  206.                     $sendMbx = "[email protected]"
  207.                     $recMbx = "[email protected]"
  208.                     $body = "Hallo smith6,`nMailBox/agenda is klaar voor deze gebruiker om trainingen te kunnen plannen. : '$($SAM)' "
  209.  
  210.                     $mailProps = @{
  211.                            
  212.                         SMTPServer = "smtp.office365.com"
  213.                         From = $sendMbx
  214.                         To = $recMbx
  215.                         Cc = "[email protected]"
  216.                         Subject = "Account is aangemaakt ($SAM)"
  217.                         UseSSL = $true
  218.                         Port = 587
  219.                         Credential = $cred
  220.                     }
  221.                     Send-MailMessage @mailProps $body
  222.  
  223.                 }
  224.                 #debugging purposes...
  225.                 Write-Debug "`$FirstName:  $($FirstName)"
  226.                 Write-Debug "`$LastName: $($LastName)"
  227.                 Write-Debug "`$Email: $($Email)"
  228.                 Write-Debug "`$StartDate: $($StartDate)"
  229.                 Write-Debug "`$EndDate: $($EndDate)"
  230.                 Write-Debug "`$copyUser: $($copyUser)"
  231.                 Write-Debug "`$FullName: $($FullName)"
  232.                 Write-Debug "`$SAM: $($SAM)"
  233.                 Write-Debug "`$Manager: $($Manager)"
  234.                 Write-Debug "`$Username: $($Username)"
  235.                 Write-Debug "`$DNSRoot: $($DNSroot)"
  236.                 Write-Debug "`$UPN: $($UPN)"
  237.                 Write-Debug "`$oStartDate: $($oStartDate)"
  238.  
  239.                 #=>debugging puproses
  240.  
  241.                 # Now, let's check the user's startdate as listed in the CSV file.  If startdate is within 48 hours of today's (Get-Date) date we'll create the user directly in AD.  Otherwise, we'll schedule a task to create the user at a later date.
  242.                 # First, we need to check if this is a New User request, 'startdate' only applies to new users...
  243.                 if ($csvFile.name -like "NS*") {
  244.                     if ( $today -eq $oStartDate) {
  245.                         Write-Debug "$(Get-Date) is due so we are creating the user immediately."
  246.  
  247.                         #Checking to see if a user already exists in AD with the same email address...
  248.                         if (Get-AdUser -Filter {mail -eq $Email}) {
  249.                             Send-Mail
  250.                             Rename-Item -Path $csvFile.FullName -NewName "$($csvFile.FullName).done" -Force
  251.                             Rename-Item -Path "C:\Users\sa.ps\Desktop\logs\transcript.log" -NewName "$($LastName).log" -Force
  252.                             Set-ItemProperty -Path "$($csvFile.FullName).done" -name IsReadOnly -Value $true
  253.  
  254.  
  255.                             Write-Debug "A user with email address $($email) already exists in AD.  We cannot add this user."
  256.                             $failedUsers+= -join($Fullname,",",$SAM,",","A user with email address $($email) already exists in AD. Skipping this user.")
  257.                             Write-CustomEventLog -message "When attempting to create user $($FullName) [SAM: $($SAM)] we found another user that exists in AD using the same email address of $($email). We have to skip this user." -entryType "Warning"
  258.                             Continue #go to next csv record.
  259.                         }#=if get-aduser
  260.                         else {
  261.                             Write-Debug "No existing user in AD with email address $($email) so we can create our user."
  262.  
  263.                             $newUserAD = @{
  264.                                 'SamAccountName'            = $SAM
  265.                                 'UserPrincipalName'         = $UPN
  266.                                 'Name'                      = $FullName
  267.                                 'DisplayName'               = $DisplayName
  268.                                 'Company'                   = $Company
  269.                                 'GivenName'                 = $FirstName
  270.                                 'Surname'                   = $LastName
  271.                                 'Title'                     = $Title
  272.                                 'Department'                = $Department
  273.                                 'Mobile'                    = $Mobile
  274.                                 'AccountPassword'           = $Password
  275.                                 'AccountExpirationDate'     = $oEndDate
  276.                                 'ChangePasswordAtLogon'     = $true
  277.                                 'Enabled'                   = $true
  278.                                 'PasswordNeverExpires'      = $false  
  279.                                 #'Country'                   = 'BE'
  280.                                 'EmailAddress'              = $UPN
  281.                             }#=>$newUserAD
  282.  
  283.                             Write-Debug "Attempting to get properties of our user to copy from..."
  284.                             #$templateUser = Get-ADUser -Identity $copyUser -Properties MemberOf | Select-Object -ExpandProperty MemberOf | Add-ADGroupMember -Members $SAM
  285.                             $templateUser = Get-ADUser -filter {SamAccountName -eq $copyUser} -Properties MemberOf
  286.                             if (-not($templateUser)) {
  287.                                 Write-Debug "We were unable to find the template user $($copyUser) so we have to skip this new AD user and go to the next row in the CSV file."
  288.                                 #$failedUsers+= -join($Fullname,",",$SAM,",","We were unable to find the template user $($copyUser) so we have to skip creating new user $($FullName) and go to the next row in the CSV file.")
  289.                                 Write-CustomEventLog -message "We were unable to find the template user $($copyUser) when attempting to create new user $($FullName) with SAM $($SAM).  Skipping the creation of this user." -entryType "Warning"
  290.                                 continue #move to next CSV row.
  291.                             } else {
  292.                                 #Let's get the OU that our template user belongs to and apply that to our new user...
  293.                                 $OU = ($templateUser.DistinguishedName).Substring(($templateUser.DistinguishedName).IndexOf(",")+1)
  294.                                 Write-Debug "Our OU for new user $($FullName) is $($OU) from copy of our template user $($copyUser) with OU of $($templateUser.DistinguishedName)"
  295.                                 #Let's update our $newUserAD properties with this OU...
  296.                                 $newUserAD['Path'] = $OU
  297.                             }#=>if/else $templateuser
  298.  
  299.                             try {
  300.                                 Write-Debug "Adding user $($FullName) to AD with the following paramaters; `n $($newUserAD | Out-String)"
  301.                                 $oNewADUser = New-ADUser @newUserAD                                
  302.                             }
  303.                             catch {
  304.                                 Write-Debug "Unable to create new user $($FullName) to AD.  Error message `n`n $Error"
  305.                                 if(-not($oNewADUser)) {
  306.                                     Write-Debug "Something went wrong with adding our new $($FullName) user to AD. `n`n $error"
  307.                                     $failedUsers+= -join($Fullname,",",$SAM,",","We were unable to add our new user $($FullName) to AD. `n`n $error `n`n Moving to next user...")
  308.                                     Write-CustomEventLog -message "We were unable to add our new user $($FullName) to AD. Skipping this user.  Full error details below; `n`n $($Error)." -entryType "Warning"
  309.                                     continue
  310.                                 }
  311.                             }
  312.                             Start-Sleep -Seconds 10
  313.                             #Adding user went well..
  314.                             Get-ADUser -Identity $copyUser -Properties MemberOf | Select-Object -ExpandProperty MemberOf | Add-ADGroupMember -Members $SAM
  315.                             $templateManager = Get-ADUser -filter {UserPrincipalName -like $Manager} -Properties * | Select-Object SamAccountName
  316.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{domainBusinessUnit = $BusinessUnit}
  317.                             #Get-ADUser -Identity $SAM | Set-ADUser -Add @{
  318.                                 #co = 'Belgium'
  319.                                 #countryCode = 56
  320.                             #}
  321.                             Get-ADUser -Identity $SAM | Set-ADUser -Manager $templateManager -Fax '+32 56 528 800'
  322.                             Start-Sleep -Seconds 5
  323.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'PreferredLanguage' = $PreferredLanguage}
  324.                             Start-Sleep -Seconds 5
  325.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'EmployeeType' = $EmployeeType}
  326.                             Start-Sleep -Seconds 5
  327.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'extensionattribute2' = $EmployeeType}
  328.                             Start-Sleep -Seconds 5
  329.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'extensionattribute3' = $BusinessUnit}
  330.                             Start-Sleep -Seconds 5
  331.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'physicalDeliveryOfficeName' = $officeLocation}
  332.                             Start-Sleep -Seconds 5
  333.                             Get-ADUser -Identity $SAM | Set-ADUser -Add @{'co'= $Country}
  334.                            
  335.                             Add-ADGroupMember -Identity MS365 -Members $SAM
  336.                             #Add-ADGroupMember -Identity MyITHubApp -Members $SAM
  337.                             #Add-ADGroupMember -Identity HRPortalGrp -Members $SAM
  338.                             Write-Debug "We created our new user $($FullName) in AD."
  339.  
  340.                             # Sleep for 45 minutes to allow the sync to complete
  341.                             Write-Host "Waiting for 35 minutes to ensure AD sync completes..."
  342.  
  343.                             Start-Sleep -Seconds 2100  # 35 minutes
  344.  
  345.                             # Azure DevOps Integration (add user to DevOps)
  346.                             $AzureDevOpsPAT = "thispersonalaccesstokencanbefoundindevopssettings"  # Replace with actual PAT
  347.                             $OrganizationName = "domainGroup"
  348.                             $ProjectId = "-4281-2c864654-2f38gtghyefrgthggbe49-77b5c7cce178"  # Replace with actual project ID
  349.                             $AzureDevOpsAuthenicationHeader = @{
  350.                                 Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)"))
  351.                             }
  352.  
  353.                             $UserBody = @{
  354.                                 accessLevel = @{
  355.                                     accountLicenseType = "stakeholder"
  356.                                 };
  357.                                 extensions = @();
  358.                                 user = @{
  359.                                     principalName = "[email protected]";
  360.                                     subjectKind = "user"
  361.                                 };
  362.                                 projectEntitlements = @(
  363.                                     @{
  364.                                         group = @{
  365.                                             groupType = "projectContributor"
  366.                                         };
  367.                                         projectRef = @{
  368.                                             id = $ProjectId
  369.                                         }
  370.                                     }
  371.                                 )
  372.                             } | ConvertTo-Json -Depth 10
  373.  
  374.                             $AddUserParameters = @{
  375.                                 Method = "POST"
  376.                                 Headers = $AzureDevOpsAuthenicationHeader
  377.                                 Uri = "https://vsaex.dev.azure.com/$OrganizationName/_apis/userentitlements?api-version=7.1"
  378.                                 Body = $UserBody
  379.                                 ContentType = "application/json"
  380.                             }
  381.  
  382.                             try {
  383.                                 $AddUserResponse = Invoke-RestMethod @AddUserParameters
  384.                                 Write-CustomEventLog -message "User $SAM added to Azure DevOps project successfully." -entryType "Information"
  385.                             } catch {
  386.                                 Write-CustomEventLog -message "Failed to add user $SAM to Azure DevOps." -entryType "Error"
  387.                             }
  388.                             $successUsers += -join($FullName,",",$SAM,",","Successfully created new AD user.")
  389.                             Write-CustomEventLog -message "Successfully created new AD User $($FullName).  AD Details included below; `n`n $($newuserAD | Out-String)" -entryType "Information"
  390.                             Write-Debug "Creating user mailbox..."
  391.  
  392.                             informsmith6
  393.                            
  394.                             # Connect to Mg-graph. The tokens and creds needed for authentication
  395.                             $appid = 'hghghfhfhfhdhsgfygrfrf529525454'
  396.                             $secret = 'lglgoflfjdfkfjfjfjfjfjfjfjfjf88f8f8f8f8f8f8'
  397.                             $tenantid = 'jgjgjgjgjgkfkfkfkfjgjgjgkfkfjf969696'
  398.                            
  399.                            
  400.                             $body =  @{
  401.                                 Grant_Type    = "client_credentials"
  402.                                 Scope         = "https://graph.microsoft.com/.default"
  403.                                 Client_Id     = $appid
  404.                                 Client_Secret = $secret
  405.                             }
  406.                            
  407.                             $connection = Invoke-RestMethod `
  408.                                 -Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token `
  409.                                 -Method POST `
  410.                                 -Body $body
  411.                             $token = $connection.access_token
  412.                            
  413.                            
  414.                             Connect-MgGraph -AccessToken ($token |ConvertTo-SecureString -AsPlainText -Force) -NoWelcome
  415.                            
  416.                             Update-MgUser -UserId $UPN -AdditionalProperties @{'extension_akhkhkhkhkfkfhfkkdhdh0_UserEmployeeCategory' = $EmployeeType}
  417.                            
  418.                            
  419.                             Disconnect-MgGraph 
  420.  
  421.  
  422.                             # This function connects to ExchangeOnPrem to mirror the mailbox
  423.                             function Connect-ExchangeOnPrem {
  424.                                 [CmdletBinding()]
  425.                                 Param(
  426.                                     $Prefix = $null
  427.                                 )
  428.                                 $Sessions = Get-PSSession | Where-Object { $_.ComputerName -match "BEMENVMBX01" }
  429.                                 If (-Not ($Sessions)) {
  430.                                     Function Get-MhExchangeServerInAdSite {
  431.                                         $ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]
  432.                                         $siteDN = $ADSite::GetComputerSite().GetDirectoryEntry().distinguishedName
  433.                                         $configNC = ([ADSI]"LDAP://RootDse").configurationNamingContext
  434.                                         $search = new-object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$configNC")
  435.                                         $objectClass = "objectClass=msExchExchangeServer"
  436.                                         $version = "versionNumber>=1937801568"
  437.                                         $site = "msExchServerSite=$siteDN"
  438.                                         $search.Filter = "(&($objectClass)($version)($site))"
  439.                                         $search.PageSize = 1000
  440.                                         [void] $search.PropertiesToLoad.Add("name")
  441.                                         [void] $search.PropertiesToLoad.Add("networkaddress")
  442.                                         $search.FindAll() | Foreach-Object {
  443.                                             [PSCustomObject]@{
  444.                                                 Name = $_.Properties.name[0]
  445.                                                 FQDN = $_.Properties.networkaddress | ForEach-Object {
  446.                                                     if ($_ -match "ncacn_ip_tcp") {
  447.                                                         $_.split(":")[1]
  448.                                                     }
  449.                                                 }
  450.                                             }
  451.                                         }
  452.                                     }
  453.                                    
  454.                                     #add all servers in the local site to an array
  455.                                     $ExchSrvrs = Get-MhExchangeServerInAdSite
  456.                                    
  457.                                     #select a random server from the current site
  458.                                     If ($ExchSrvrs.count -gt 1) {
  459.                                         $random = Get-Random -Minimum 0 -Maximum $ExchSrvrs.count
  460.                                         $ExchSrvrFqdn = $ExchSrvrs[$random]
  461.                                     } Else {
  462.                                         $ExchSrvrFqdn = $ExchSrvrs[0]
  463.                                     }
  464.                            
  465.                                     $URI = "http://$($ExchSrvrFqdn.Fqdn)/PowerShell/?SerializationLevel=Full"
  466.                                     $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $URI -Authentication Kerberos -ErrorAction Stop
  467.                                     If ($Prefix) {
  468.                                         Import-PSSession $Session -DisableNameChecking -Prefix $Prefix | Out-Null    
  469.                                     } Else {
  470.                                         Import-PSSession $Session -DisableNameChecking -AllowClobber | Out-Null
  471.                                     }
  472.                                     Write-Verbose "Session connected to $($ExchSrvrFqdn.Fqdn)"
  473.                                 } Else {
  474.                                     Write-Warning "Already connected to Exchange"
  475.                                 }
  476.                             }
  477.                            
  478.                        
  479.                             #Then you would be able to connect to an Exchange server via:
  480.                            
  481.                             #Connect-ExchangeOnPrem
  482.                             #Enable-RemoteMailbox $sam -RemoteRoutingAddress "$($_.SAMAccountName)@domain.mail.onmicrosoft.com"
  483.                             <#And if you wanted there to be no conflict with the EXO module:#>
  484.                            
  485.                             Connect-ExchangeOnPrem -Prefix 'OP' # As in "on-premises"
  486.                             Enable-OPRemoteMailbox $SAM -RemoteRoutingAddress "[email protected]"
  487.                              
  488.                            
  489.                             <#Edit: Forgot you would need to update EXCHSRV value with the naming standard (or list of names if disparate)
  490.                             for your Exchange servers in your org if you care to not try re-connecting when you already have an established connection.
  491.                             Line I'm referencing:
  492.                             #>
  493.                            
  494.                             $Sessions = Get-PSSession | Where-Object { $_.ComputerName -match "EXCHSRV" }
  495.                         }#=>else get-aduser
  496.  
  497.  
  498.                     } else {
  499.                         write-debug "Start date beyond 72hrs, leaving file unchanged!"
  500.                         break
  501.        
  502.             }#=>ForEach $user !$isScheduled
  503.            
  504.             Write-Debug "Renaming our current csv file $($csvFile.FullName) and addding a .done extension. Also making the file read-only."
  505.             Stop-Transcript
  506.             # Rename the CSV file with the .done extension
  507.             $NewFileName = Join-Path -Path $Csvfile.Directory.FullName -ChildPath ($Csvfile.BaseName + ".done")
  508.             Rename-Item -Path $Csvfile.FullName -NewName $NewFileName -Force
  509.  
  510.             # Set the renamed CSV file as read-only
  511.             $NewFileFullPath = Join-Path -Path $Csvfile.Directory.FullName -ChildPath ($Csvfile.BaseName + ".done")
  512.             Set-ItemProperty -Path $NewFileFullPath -Name IsReadOnly -Value $true
  513.  
  514.  
  515.                 }
  516.             }
  517.         }
  518.     }
  519. }
  520.  
  521. Disconnect-ExchangeOnline -Confirm:$false
Tags: PS
Add Comment
Please, Sign In to add comment