【发布时间】:2022-01-01 03:08:45
【问题描述】:
我发现了一个 Powershell 脚本,它可以将 Office 365 用户同步到 Mailchimp 联系人。它运行良好,但唯一的问题是我希望它在 Mailchimp 中“取消订阅”或“存档”联系人,如果 Office 365 中的先前许可用户不再具有任何活动许可证。
现在,如果 Office 365 中的用户许可证发生更改,它将更新许可证,但如果所有许可证都已删除,则不会。我认为脚本中的以下行是导致没有许可证的用户无法同步的原因,但我不知道解决它的最佳方法...
$users = Get-MsolUser | Where-Object {$_.islicensed}
如果我将此行更改为$users = Get-MsolUser -All,那么无论用户是否获得许可,它都会检索用户,但这仍然不能完全解决我的问题,因为我的目标仍然是只同步许可用户,但要确保一旦 O365 用户未获得许可,他们将在 Mailchimp 中“取消订阅”或“存档”(两者都可以)。
我正在粘贴下面的整个脚本,并在我上面提到的代码行旁边添加了一个
$user = "abc"
$apiKey = "544492bf22f6895d4ae-us15"
$pair = "${user}:${apiKey}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$Headers = @{
Authorization = $basicAuthValue
}
$baseUri = "https://us15.api.mailchimp.com"
$listInfo = @{
listName = "Office 365 Customer Sync"
company = "abc"
address1 = "abc"
address2 = " "
city = "abc"
state = "NY"
zip = "11111"
country = "US"
phone = ""
permission_reminder = "You are receiving this email because you are a client of Abtech Technologies"
from_name = "John Doe"
from_email = "jdoe@email.com"
subject = ""
language = "en"
}
$Office365members = @()
Connect-MsolService
function Ensure-MailChimpList ($ListName) {
$lists = Invoke-RestMethod -URI $baseUri/3.0/lists?offset=0"&"count=100 -Method Get -Headers $Headers
if ($lists.lists.name -notcontains $ListName) {
$list = New-MailChimpList -ListInfo $listInfo
return $list
}
else {
$list = $lists.lists | Where-object {$_.name -contains $listName}
return $list
}
}
function New-MailChimpList ($ListInfo) {
$listBody = @{
name = $listInfo.listName
contact = @{
company = $listInfo.company
address1 = $listInfo.address1
address2 = $listInfo.address2
city = $listInfo.city
state = $listInfo.state
zip = $listInfo.zip
country = $listInfo.country
phone = $listInfo.phone
}
permission_reminder = $listInfo.permission_reminder
campaign_defaults = @{
from_name = $listInfo.from_name
from_email = $listInfo.from_email
subject = $listInfo.subject
language = $listInfo.language
}
email_type_option = $false
}
$listBody = $listBody | ConvertTo-Json
$newList = Invoke-RestMethod -URI $baseUri/3.0/lists -Method POST -Headers $Headers -Body $listBody
return $newList
}
function Get-MailChimpListSegments {
$segments = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/segments?offset=0"&"count=200 -Method Get -Headers $Headers
return $segments
}
function Get-MailChimpListMergeFields {
$mergeFields = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/merge-fields -Method Get -Headers $Headers
return $mergeFields
}
function New-MailChimpListMergeField ($Name, $Type, $Tag) {
$merge_field = @{
name = $Name
type = $Type
tag = $Tag
}
$merge_field = $merge_field | ConvertTo-Json
Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/merge-fields -Method POST -Headers $Headers -Body $merge_field
}
function New-MailChimpListBatch ($MemberBatch) {
$body = @{
members = $MemberBatch
update_existing = $true
}
$body = $body | ConvertTo-Json -Depth 10
$batchresult = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId -Method POST -Headers $Headers -Body $body
return $batchresult
}
function New-MailChimpListMember ($email, $FirstName, $LastName, $Company, $Licenses) {
$merge_fields = @{
FNAME = $FirstName
LNAME = $LastName
COMPANY = $Company
LICENSES = $Licenses
}
$member = @{
email_address = $email
status = "subscribed"
merge_fields = $merge_fields
}
return $member
}
function Update-MailChimpListMember ($ExistingMember, $Office365Member) {
$merge_fields = @{
FNAME = $Office365Member.FirstName
LNAME = $Office365Member.LastName
COMPANY = $Office365Member.Company
LICENSES = $Office365Member.Licenses
}
$member = @{
email_address = $Office365Member.Email
status = $existingMember.Status
merge_fields = $merge_fields
}
return $member
}
# function Unsubscribe-MailChimpListMember ($ExistingMember) {
# $member = @{
# email_address = $ExistingMember.Email
# status = "unsubscribed"
# }
# return $member
# Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/members/$($existingMember.SubscriberHash) -Method PATCH -Headers $Headers -Body $member
# }
function Get-ExistingMailChimpListMembers {
$existingMembers = $null
$existingmembers = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/members?offset=0"&"count=100 -Method Get -Headers $Headers
for ($i = 100; $i -le $existingMembers.total_items; $i += 100) {
$members = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/members?offset=$i"&"count=100 -Method Get -Headers $Headers
$existingMembers.members += $members.members
}
return $existingMembers
}
function New-LicenseSegment ($SkuPartNumber) {
$conditions = @()
$conditionproperty = @{
condition_type = "TextMerge"
field = "LICENSES"
op = "contains"
value = $SkuPartNumber.TrimStart("License: ")
}
$conditions += $conditionproperty
$segment = @{
name = $SkuPartNumber
options = @{
match = "any"
conditions = $conditions
}
}
$segment = $segment | ConvertTo-Json -Depth 10
$newSegment = Invoke-RestMethod -URI $baseUri/3.0/lists/$listId/segments -Method POST -Headers $Headers -Body $segment
return $newSegment
}
function Create-ExistingMemberCollection ($ExistingMembers) {
$existingMemberCollection = @()
foreach ($existingmember in $existingmembers) {
$memberObject = New-Object PSObject -Property @{
Licenses = $existingmember.merge_fields.LICENSES
FirstName = $existingmember.merge_fields.FNAME
LastName = $existingmember.merge_fields.LNAME
Company = $existingmember.merge_fields.COMPANY
Email = $existingmember.email_address
SubscriberHash = $existingmember.id
Status = $existingmember.status
}
$existingMemberCollection += $memberObject
}
return $existingMemberCollection
}
function Create-UploadBatch ($collection) {
# Upload the collection in batches of 100
$counter = [pscustomobject] @{ Value = 0 }
$batchsize = 100
$batches = $collection | Group-Object -Property { [math]::Floor($counter.Value++ / $batchSize) }
foreach ($batch in $batches) { New-MailChimpListBatch -MemberBatch $batch.Group}
}
# Check whether list exists and create it if it doesn't
$listID = (Ensure-MailChimpList -ListName $listInfo.listName).id
# Check for current merge fields in list
Write-Host "Retrieving Merge Fields"
$mergeFields = Get-MailChimpListMergeFields
$updateSegments = $false
$requiredMergeFields = "Company", "Licenses"
foreach ($requiredMergeField in $requiredMergeFields) {
if (!$mergeFields.merge_fields.Name.contains($requiredMergeField)) {
Write-Host "Creating Merge Field: $requiredMergeField" -ForegroundColor Yellow
$newMergeField = New-MailChimpListMergeField -Name $requiredMergeField -Type text -Tag $requiredMergeField.ToUpper()
}
}
# Retrieve existing segments, then filter by license related segments
$existingSegments = Get-MailChimpListSegments
$existingLicenseSegments = $existingSegments | Where-Object {$_.segments.name -match "License: "}
$requiredSegments = @()
# Create collection containing required info for all users in all tenants
Write-Host "Retrieving users and license info" -ForegroundColor Blue
$users = $null
$users = Get-MsolUser | Where-Object {$_.islicensed} <----------------------------------------------
$company = (Get-MsolCompanyInformation).DisplayName
foreach ($user in $users) {
[string[]]$userLicenses = $null
foreach ($license in $user.Licenses.AccountSku.SkuPartNumber) {
$userLicenses += "'$license'"
}
$userLicensesString = $userLicenses -join ','
# Check if these licenses already have segments created or queued
foreach ($license in $userlicenses) {
$expectedSegmentName = "License: $license"
if ($existingLicenseSegments.segments.Name -notcontains $expectedSegmentName -and $requiredSegments -notcontains $expectedSegmentName) {
$requiredSegments += $expectedSegmentName
Write-Host "Adding $expectedSegmentName to required segments list. Update pending." -ForegroundColor Yellow
$updateSegments = $true
}
}
$firstName = $user.FirstName
if (!$user.FirstName) {
$firstName = $user.DisplayName.Split(" ")[0]
}
$lastName = $user.LastName
if (!$user.lastName -and !$user.firstname) {
$lastName = $user.DisplayName.Split(" ") | Where-Object {$_ -notcontains $user.DisplayName.Split(" ")[0]}
$lastName = $lastName -join " "
}
elseif (!$user.lastName -and $user.firstname) {
$lastname = ""
}
elseif (!$user.LastName -and !($user.DisplayName.Split(" ") | Where-Object {$_ -notcontains $user.DisplayName.Split(" ")[0]})) {
$lastname = ""
}
$email = $user.UserPrincipalName
$memberObject = New-Object PSObject -Property @{
Licenses = $userLicensesString
FirstName = $firstName
LastName = $lastName
Company = $company
Email = $email
}
$Office365members += $memberObject
}
Write-Host "Retrieved $($office365Members.count) licensed users" -ForegroundColor Green
# If an update is required, add new segments
if ($updateSegments) {
Write-Host "New segments required: $requiredSegments" -ForegroundColor Green
# Create new license segments
if ($requiredSegments.count -gt 0) {
foreach ($requiredSegment in $requiredSegments) {
Write-Host "Creating new segment - $requiredSegment" -ForegroundColor Blue
$newSegment = New-LicenseSegment -SkuPartNumber $requiredSegment
}
}
}
# Check if members exist in list
# Build list of existing members
Write-Host "Getting existing members"
$existingMembers = (Get-ExistingMailChimpListMembers).members
$newMemberCollection = @()
# Check if Office 365 users already exist in mailchimp. If they don't, add them to a collection for upload
foreach ($member in $Office365members) {
if ($existingMembers.email_address -notcontains $member.Email) {
Write-Host "Adding $($member.firstName) $($member.lastName) to new subscriber collection" -ForegroundColor Green
$newMemberObject = New-MailChimpListMember -email $member.Email -FirstName $member.FirstName -LastName $member.LastName -Licenses $member.Licenses -Company $member.Company
$newMemberCollection += $newMemberObject
}
}
Create-UploadBatch -collection $newMemberCollection
# Retrieve updated list of existing members
$existingMembers = (Get-ExistingMailChimpListMembers).members
$existingMemberCollection = Create-ExistingMemberCollection -ExistingMembers $existingMembers
# Update users when details have changed.
$updatedMemberCollection = @()
foreach ($existingMember in $existingMemberCollection) {
$office365Member = $null
$office365Member = $Office365members | Where-Object {$_.Email -contains $existingMember.Email}
if ($office365member) {
if ($office365Member.FirstName -notmatch $existingMember.FirstName -or `
$office365Member.LastName -notmatch $existingMember.LastName -or `
$office365Member.Licenses -notmatch $existingMember.Licenses -or `
$office365Member.Company -notmatch $existingMember.Company){
Write-Host "Updating record for $($existingMember.Email)" -ForegroundColor Yellow
$updatedMemberObject = Update-MailChimpListMember -ExistingMember $existingMember -Office365Member $office365Member
$updatedMemberCollection += $updatedMemberObject
}
}
}
Create-UploadBatch ($updatedMemberCollection)
# Unsubscribe users who no longer exist in Office 365
# $unsubscribedMemberCollection = @()
# foreach ($existingMember in $existingMemberCollection) {
# if ($Office365members.License -notcontains $existingmember.License -and $existingmember.status -notcontains "unsubscribed") {
# Write-Host "$($existingmember.License) is no longer licensed in Office 365, unsubscribing." -ForegroundColor Red
# $unsubscribedMemberObject = Unsubscribe-MailChimpListMember -ExistingMember $existingMember
# $unsubscribedMemberCollection += $unsubscribedMemberObject
# }
# }
# Create-UploadBatch ($unsubscribedMemberCollection)
【问题讨论】:
标签: powershell office365 mailchimp