Глава 10. Склеиваем всё это воедино

Содержание

Глава 10. Склеиваем всё это воедино
Примеры продуктов (ежедневного применения)
Microsoft Exchange
Очистка базы данных с тем, чтобы Почтовые ящики появлялись в отключённом состоянии
Поиск отключённых Почтовых ящиков
Выделение Сообщение получено от
Активные синхронизации статистик
Отслеживание сообщений
Поиск сообщений Почтовый ящик/ Удалённые
Отчёт о квотах Exchange
Настройка квот
Active Directory
Экспорт Участников группы
Установка значения для атрибутов AD
Экспорт атрибутов AD
Добавление участников в группу из текстового файла
Удаление участников в группу из текстового файла
Office 365
Отчёт Почтового ящика Exchange Online
Отслеживание сообщения Exchange Online
Поиск унифицированного журнала
Azure AD
Добавление пользователей в группу Azure AD из текстового файла UPN
Удаление пользователей в группе Azure AD из текстового файла UPN
Проверка является ли пользователь участником группы
Добавление в роль Администраторов
Проверка ошибок предоставления пользователей Azure AD
Операции с файлом Text/CSV
Regex
Выводы

Это последняя глава данной книги и в ней я покажу вам как пользоваться теми знаниями, которые вы получили к данному моменту в практическом сценарии. Я также поделюсь некоторыми кодами шпаргалок из различных продуктов, которыми вы можете пользоваться для своих повседневных потребностей.

Вот соответствующая ситуация: Вы получили текстовый файл из своей системы персонала, который содержит список имён учётных записей (Рисунок 10-1), который вы хотите добавить в некую группу Active Directory с тем, чтобы они имели возможность доступа к определённому совместному ресурсу файлов, для которого данная группа AD обладает полномочиями или получить некое прикладное приложение, которое помещается в их устройства на основе их участия в данной группе AD.

 

Рисунок 10-1


Отображение примера текстового файла пользователей

Шаг 1: добавляем заголовок своего сценария (см. Рисунок 10-2):


<#
    .NOTES
    ===========================================================
    Created with:     ISE
    Created on:       9/6/2021 1:46 PM
    Created by:       Vikas Sukhija
    Organization:
    Filename:         ADDUserstoGroupfromText.ps1
    ===========================================================
    .DESCRIPTION
    Добавляет всех пользователей из текстового файла в группу AD
#>
 	   
 

Рисунок 10-2


Отображение заголовков в ISE

Шаг 2: импорт всех модулей, которые вы будете применять для данного сценария:

  1. Модуль vsadmin упростит вашу жизнь для необходимых операций составления сценария.

  2. Модули Active Directory

Если вы не желаете пользоваться модулем vsadmin, тогда просто воспользуйтесь вместо этого необходимыми функциями.


import-module vsadmin
import-module Activedirectory
 	   

Шаг 3: добавляем для вашего сценария некие переменные и журналы:


$log = Write-Log -Name "ADDUser2Group-Log" -folder "logs" -Ext "log"
$users = get-content "c:\temp\users.txt"
$Adgroup = "ADgroup1"
$logrecyclelimit = "60" #для отправки в корзину по истечению 60 дней
 	   

Шаг 4: приступаем к реальному действию:


Write-Log -Message "Start...............script" -path $log
$users | foreach-object{
  $user = $_.trim() #triming fro any whitespace
  Write-Log -Message "Processing..........$user" -path $log
  $getusermemberof = Get-ADUserMemberOf -User $user -Group $Adgroup #checking if user si already member
  if($getusermemberof -eq $true){ #if users is already mebe rjust write it to log
    Write-Log -Message "$user is already member of $Adgroup" -path $log
  }
  else{
    Write-Log -Message "ADD $user to $Adgroup" -path $log
    Add-ADGroupMember -identity $Adgroup -members $user
    if($error){ #error checking, if error occurs add in log
      Write-Log -Message "Error - ADD $user to $Adgroup" -path $log
     $error.clear() # clearing the error as it has already been captuire for this iteration
    }
    else{
      Write-Log -Message "Success - ADD $user to $Adgroup" -path $log
    }
  }
}
 	   

Шаг 5: Отправка в корзину журналов или очистка соответствующих сеансов (см. Листинг 10-1):


#####################Очистка журналов#############################
Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit -Confirm:$false

Write-Log -Message "Script Finished" -path $log
 	   

Склеиваем всё воедино для формирования привлекательного сценария, которым делимся в Листинге 10.1

 

Листинг 10-1. Код шпаргалки примера шаблона сценария


<#
    .NOTES
    ==========================================================
    Created with:     ISE
    Created on:       9/6/2021 1:46 PM
    Created by:       Vikas Sukhija
    Organization:
    Filename:         ADDUserstoGroupfromText.ps1
    ==========================================================
    .DESCRIPTION
    Это добавляет всех пользователей из текстового файла в группу AD
#>
###############Импорт модулей и функций#####################
import-module vsadmin
import-module Activedirectory
##############Добавляем журналы и переменные############################
$log = Write-Log -Name "ADDUser2Group-Log" -folder "logs" -Ext "log"
$users = get-content "c:\temp\users.txt"
$Adgroup = "ADgroup1"
$logrecyclelimit = "60" #to recycle the logs after 60 days
################################################################
Write-Log -Message "Start...............script" -path $log
$users | foreach-object{
  $user = $_.trim() #отсекаем все пробельные символы
  Write-Log -Message "Processing..........$user" -path $log
  $getusermemberof = Get-ADUserMemberOf -User $user -Group $Adgroup #проверяем является ли уже участником пользователь si
  if($getusermemberof -eq $true){ #когда пользователь уже участник, просто заносим его в журнал
    Write-Log -Message "$user is already member of $Adgroup" -path $log
  }
  else{
    Write-Log -Message "ADD $user to $Adgroup" -path $log
    Add-ADGroupMember -identity $Adgroup -member $user
    if($error){ #error checking, if error occurs add in log
      Write-Log -Message "Error - ADD $user to $Adgroup" -path $log
      $error.clear() # создаём ошибку когда он был уже перехвачен для повтора
    }
    else{
      Write-Log -Message "Success - ADD $user to $Adgroup" -path $log
    }
  }
}
#####################Очищаем журналы#############################
Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit -Confirm:$false
Write-Log -Message "Script Finished" -path $log
 	   

Давайте выполним этот код шпаргалки изменив значение переменной adgroup и добавив в свой текстовый файл пользователей, якобы для промышленной среды. Смотрите Рисунок 10-3).

 

Рисунок 10-3


Отображение исполнения сценария ADDUserstoGroupFromText.ps1

Аналогичным образом вы можете создавать множество сценариев для различных промышленных применений. За последние 10 лет я поделился с сообществом сотнями сценариев, к которым вы можете получить доступ через приводимую ниже ссылку и которые можете изменять под свои потребности. Большинство этих сценариев разделяют те же самые принципы, которые описаны в данной книге: https://techwizard.cloud/downloads/.

Примеры продуктов (ежедневного применения)

В данной главе я делюсь фрагментами кода, которые вы можете применять как есть или сочетать со своими сценариями для ежедневных административных задач. По причине своего обожания Exchange, я пользуюсь Microsoft Exchange☺. Здесь выдержки сценария Exchange, которые вы можете применять на ежедневной основе.

Microsoft Exchange

Очистка базы данных с тем, чтобы Почтовые ящики появлялись в отключённом состоянии


Get-MailboxServer | Get-MailboxDatabase | Clean-MailboxDatabase
		

Поиск отключённых Почтовых ящиков


Get-ExchangeServer | Where-Object {$_.IsMailboxServer -eq $true} | ForEach-Object { Get-MailboxStatistics -Server $_.Name | Where-Object {$_.DisconnectDate -notlike ''}}
		

Выделение Сообщение получено от


Get-distributiongroup "dl name" | foreach {$_.AcceptMessagesonlyFrom} | add-content "c:/output/abc.txt"
		

Активные синхронизации статистик


Get-CASMailbox -ResultSize unlimited | where {$_.ActiveSyncEnabled -eq "true"} | ForEach-Object {GetActiveSyncDeviceStatistics -Mailbox:$_.identity} | select Devicetype, DeviceID,DeviceUserAgent, FirstSyncTime, LastSuccessSync, Identity, DeviceModel, DeviceFriendlyName, DeviceOS | Export-Csv c:\activesync.csv
		

Отслеживание сообщений


Get-transportserver | Get-MessageTrackingLog -Start "03/09/2015 00:00:00 AM" -End "03/09/2015 11:59:59 PM" -sender "vikas@lab.com" -resultsize unlimited | select Timestamp,clientip, ClientHostname,ServerIp,ServerHostname,sender,EventId,MessageSubject, TotalBytes , SourceContext,ConnectorId,Source , InternalMessageId , MessageId ,@{Name="Recipents";Expression={$_.recipients}} | export-csv c:\track.csv
		

Поиск сообщений Почтовый ящик/ Удалённые

Только поиск:


import-csv c:\tmp\messagesubject.csv | foreach {Search-Mailbox $_.alias -SearchQuery subject:"Test SUbject" -TargetMailbox "Exmontest" -TargetFolder "Logs" -LogOnly -LogLevel Full} >c:\tmp\output.txt
		

Удаление:


import-csv c:\tmp\messagesubject.csv | foreach {Search-Mailbox $_.alias -SearchQuery subject:"Test Schedule" -DeleteContent -force} >c:\tmp\output.txt
		

Удаление и регистрация:


Get-transportserver
		

Отчёт о квотах Exchange

Этот пример находится также и в Export-CSV.


#форматирование даты
$date = get-date -format d
$date = $date.ToString().Replace("/", "-")
$output = ".\" + "QuotaReport_" + $date + "_.csv"
Collection = @()
Get-Mailbox -ResultSize Unlimited | foreach-object{
$st = get-mailboxstatistics $_.identity
$TotalSize = $st.TotalItemSize.Value.ToMB()
$user = get-user $_.identity
$mbxr = "" | select DisplayName,Alias,RecipientType,TotalItemSizeinMB, QuotaStatus,
UseDatabaseQuotaDefaults,IssueWarningQuota,ProhibitSendQuota,ProhibitSendReceiveQuota,
Itemcount, Email,ServerName,Company,Hidden, OrganizationalUnit,
RecipientTypeDetails,UserAccountControl,Exchangeversion

$mbxr.DisplayName = $_.DisplayName
$mbxr.Alias = $_.Alias
$mbxr.RecipientType = $user.RecipientType
$mbxr.TotalItemSizeinMB = $TotalSize
$mbxr.QuotaStatus = $st.StorageLimitStatus
$mbxr.UseDatabaseQuotaDefaults = $_.UseDatabaseQuotaDefaults
$mbxr.IssueWarningQuota = $_.IssueWarningQuota.Value
$mbxr.ProhibitSendQuota = $_.ProhibitSendQuota.Value
$mbxr.ProhibitSendReceiveQuota = $_.ProhibitSendReceiveQuota.Value
$mbxr.Itemcount = $st.Itemcount
$mbxr.Email = $_.PrimarySmtpAddress
$mbxr.ServerName = $st.ServerName
$mbxr.Company = $user.Company
$mbxr.Hidden = $_.HiddenFromAddressListsEnabled
$mbxr.RecipientTypeDetails = $_.RecipientTypeDetails
$mbxr.OrganizationalUnit = $_.OrganizationalUnit
$mbxr.UserAccountControl = $_.UserAccountControl
$mbxr.ExchangeVersion= $_.ExchangeVersion
$Collection += $mbxr
}
 #экспорт собранной коллекции в csv , надлежащим образом определяем путь $output
$Collection | export-csv $output
		

Настройка квот

Предел почтового ящика в 1ГБ (обязан иметь включённым значение $false)


set-mailbox testmailbox -UseDatabaseQuotaDefaults $false -IssueWarningQuota 997376KB -ProhibitSendQuota 1048576KB -ProhibitSendReceiveQuota 4194304KB
		

Предел почтового ящика в 2ГБ (обязан иметь включённым значение $false)


set-mailbox "testmailbox" -UseDatabaseQuotaDefaults $false -IssueWarningQuota 1.75GB -ProhibitSendQuota 2GB -ProhibitSendReceiveQuota 4GB
		

Предел почтового ящика в 3ГБ (обязан иметь включённым значение $false)


set-mailbox "testmailbox" -UseDatabaseQuotaDefaults $false -IssueWarningQuota 2.75GB -ProhibitSendQuota 3GB -ProhibitSendReceiveQuota 5GB
		

Active Directory

Active Directory это дорога жизни для всех продуктов Microsoft. Применяя PowerShell вы можете автоматизировать различные компоненты Active Directory. К счастью, Microsoft создала для такого задания собственный модуль Active Directory.

Ниже приводятся методы, которые вы можете применять для написания сценариев Active Directory при помощи PowerShell:

  • Модуль Active Directory

  • Оболочка Quest Management для Active Directory

  • ADSI (выходит за рамки этой книги)

В прошлом моим любимчиком была оболочка Quest Management, за которой следовал модуль Active Directory Microsoft. Оболочка Quest бесплатна и её можно выгружать. Однако Microsoft добавила обновления, так что, на мой взгляд, теперь он на уровне или даже лучше чем Quest.

Ещё одна из причин, по которой модуль Active Directory обладает приоритетом, на мой взгляд, состоит в том, что модуль AD Quest больше не является бесплатным, хотя вы ещё можете найти его старую версию. Я обнаружил ей по приводимой ниже ссылке (если вы хотите применять его промышленным образом, убедитесь что это не потребует лицензирования).

Я призываю вас применять модуль Active Directory Microsoft, но всё ещё имеется множество администраторов или организаций, пользующихся Quest, причём как бесплатно, так и приобретая его. Выгрузите бесплатную версию AD Quest (1.5.1) по следующей ссылке (найдена через Google). Смотрите Рисунок 10-4).

 

Рисунок 10-4


Отображение модуля AD Quest

Экспорт Участников группы

Сработает лишь одна строка кода:

При помощи Quest:


Get-QADGroupMember "group Name" | select Name, Type | Export-Csv .\members.csv
		

При помощи модуля Active Directory:


Get-ADGroup -identity "group Name" -Properties member | Select-Object -ExpandProperty member | Get-ADUser -Properties DisplayName,Samaccountname,mail,employeeid | export-csv c:\exportgroup.csv -notypeinfo
		

Установка значения для атрибутов AD

Вот пример кода, который может применяться для настройки атрибутов AD:

При помощи Quest:


Set-QADUser -identity samaccountname -ObjectAttributes @{extensionattribute10 = "IntuneCommCompleted"}
		

При помощи модуля Active Directory:


Set-ADUser -identity samaccountanme -replace @{"extensionattribute10" = "IntuneCommCompleted"}
		

Экспорт атрибутов AD

Этот пример служит вызову Excel а также в качестве использования Quest ☺:


# вызов excel для записи получаемых результатов
$objExcel = new-object -comobject excel.application
$workbook = $objExcel.Workbooks.Add()
$worksheet=$workbook.ActiveSheet
$objExcel.Visible = $False # true или false для настройки видимости на экране или нет
$cells=$worksheet.Cells
# define top level cell
$cells.item(1,1)="UserId"
$cells.item(1,2)="FirstName"
$cells.item(1,3)="LastName"
$cells.item(1,4)="Employeeid"
$cells.item(1,5)="email"
$cells.item(1,6)="Office"
$cells.item(1,7)="Department"
$cells.item(1,8)="Title"
$cells.item(1,9)="Company"
$cells.item(1,10)="City"
$cells.item(1,11)="State"
$cells.item(1,12)="Country"
#intitialize row out of the loop
$row = 2
#импорт оболочки управления quest
if ( (Get-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin Quest.ActiveRoles.ADManagement
}
$data = get-qaduser -IncludedProperties "CO", "extensionattribute1" #-sizelimit 0
#цикл по пользователям
foreach ($i in $data){
#инициализация столбца внутри цикла с тем, чтобы он всегда возвращал цикл обратно в столбец 1
$col = 1
$userid=$i.Name
$FisrtName=$i.givenName
$LastName=$i.sn
$Employeeid=$i.extensionattribute1
$email=$i.PrimarySMTPAddress
$office=$i.Office
$Department=$i.Department
$Title=$i.Title
$Company=$i.Company
$City=$i.l
$state=$i.st
$Country=$i.CO
Write-host "Processing.................................$userid"
$cells.item($row,$col) = $userid
$col++
$cells.item($row,$col) = $FisrtName
$col++
$cells.item($row,$col) = $LastName
$col++
$cells.item($row,$col) = $Employeeid
$col++
$cells.item($row,$col) = $email
$col++
$cells.item($row,$col) = $office
$col++
$cells.item($row,$col) = $Department
$col++
$cells.item($row,$col) = $Title
$col++
$cells.item($row,$col) = $Company
$col++
$cells.item($row,$col) = $City
$col++
$cells.item($row,$col) = $state
$col++
$cells.item($row,$col) = $Country
$col++
$row++}
#форматирование excel
$range = $objExcel.Range("A2").CurrentRegion
$range.ColumnWidth = 30
$range.Borders.Color = 0
$range.Borders.Weight = 2
$range.Interior.ColorIndex = 37
$range.Font.Bold = $false
$range.HorizontalAlignment = 3
# Заголовки жирным шрифтом
$cells.item(1,1).font.bold=$True
$cells.item(1,2).font.bold=$True
$cells.item(1,3).font.bold=$True
$cells.item(1,4).font.bold=$True
$cells.item(1,5).font.bold=$True
$cells.item(1,6).font.bold=$True
$cells.item(1,7).font.bold=$True
$cells.item(1,8).font.bold=$True
$cells.item(1,9).font.bold=$True
$cells.item(1,10).font.bold=$True
$cells.item(1,11).font.bold=$True
$cells.item(1,12).font.bold=$True
#сохраняем в файл excel
$filepath = "c:\exportAD.xlsx" #сохраняем свой файл excel
$workbook.saveas($filepath)
$workbook.close()
$objExcel.Quit()
		

Тот же пример с использованием естественного модуля Active Directory:


# вызов excel для записи получаемых результатов
$objExcel = new-object -comobject excel.application
$workbook = $objExcel.Workbooks.Add()
$worksheet=$workbook.ActiveSheet
$objExcel.Visible = $True # true или false для настройки видимости на экране или нет
$cells=$worksheet.Cells
# define top level cell
$cells.item(1,1)="UserId"
$cells.item(1,2)="FirstName"
$cells.item(1,3)="LastName"
$cells.item(1,4)="Employeeid"
$cells.item(1,5)="email"
$cells.item(1,6)="Office"
$cells.item(1,7)="Department"
$cells.item(1,8)="Title"
$cells.item(1,9)="Company"
$cells.item(1,10)="City"
$cells.item(1,11)="State"
$cells.item(1,12)="Country"
#intitialize row out of the loop
$row = 2
#импорт оболочки управления AD
Import-module Activedirectory
$data = Get-ADUser -Filter {Enabled -eq $True} -Properties extensionattribute1,mail,physicalDeliveryOfficeName,Department,title,Company,l,st,co -ResultSetSize 1000 #define the size
#цикл по пользователям
foreach ($i in $data){
#инициализация столбца внутри цикла с тем, чтобы он всегда возвращал цикл обратно в столбец 1
$col = 1
$userid=$i.Name
$FisrtName=$i.givenName
$LastName=$i.surname
$Employeeid=$i.extensionattribute1
$email=$i.mail
$office=$i.physicalDeliveryOfficeName
$Department=$i.Department
$Title=$i.Title
$Company=$i.Company
$City=$i.l
$state=$i.st
$Country=$i.CO
Write-host "Processing.................................$userid"
$cells.item($row,$col) = $userid
$col++
$cells.item($row,$col) = $FisrtName
$col++
$cells.item($row,$col) = $LastName
$col++
$cells.item($row,$col) = $Employeeid
$col++
$cells.item($row,$col) = $email
$col++
$cells.item($row,$col) = $office
$col++
$cells.item($row,$col) = $Department
$col++
$cells.item($row,$col) = $Title
$col++
$cells.item($row,$col) = $Company
$col++
$cells.item($row,$col) = $City
$col++
$cells.item($row,$col) = $state
$col++
$cells.item($row,$col) = $Country
$col++
$row++}
#форматирование excel
$range = $objExcel.Range("A2").CurrentRegion
$range.ColumnWidth = 30
$range.Borders.Color = 0
$range.Borders.Weight = 2
$range.Interior.ColorIndex = 37
$range.Font.Bold = $false
$range.HorizontalAlignment = 3
# Заголовки жирным шрифтом
$cells.item(1,1).font.bold=$True
$cells.item(1,2).font.bold=$True
$cells.item(1,3).font.bold=$True
$cells.item(1,4).font.bold=$True
$cells.item(1,5).font.bold=$True
$cells.item(1,6).font.bold=$True
$cells.item(1,7).font.bold=$True
$cells.item(1,8).font.bold=$True
$cells.item(1,9).font.bold=$True
$cells.item(1,10).font.bold=$True
$cells.item(1,11).font.bold=$True
$cells.item(1,12).font.bold=$True
#сохраняем свой файл excel
$filepath = "c:\exportAD.xlsx" #сохраняем свой файл excel
$workbook.saveas($filepath)
$workbook.close()
$objExcel.Quit()
		

Добавление участников в группу из текстового файла

При помощи оболочки управления Quest:


$users = Get-Content C:\Users.txt   # samccountnames of users in text file
$groupname = "Group Name"
$users | ForEach-Object{
$user = $_
Write-host "adding $user to $groupname" -foregroundcolor green
Add-QADGroupMember -Identity $groupname -Member $user
}
		

Аналогично, при помощи модуля Active Directory:


$users = Get-Content C:\Users.txt    # samccountnames of users in text file
$groupname = "Group Name"
$users | ForEach-Object{
$user = $_
Write-host "adding $user to $groupname" -foregroundcolor green
Add-ADGroupMember -id $groupname -members $user
}
		

Удаление участников в группу из текстового файла

При помощи оболочки управления Quest:


$users = Get-Content C:\Users.txt   # samccountnames of users in text file
$groupname = "Group Name"
$users | ForEach-Object{
$user = $_
Write-host "adding $user to $groupname" -foregroundcolor green
Remove-QADGroupMember -Identity $groupname -Member $user -confirm:$false
}
		

Аналогично, при помощи модуля Active Directory:


$users = Get-Content C:\Users.txt    # samccountnames of users in text file
$groupname = "Group Name"
$users | ForEach-Object{
$user = $_
Write-host "adding $user to $groupname" -foregroundcolor green
Remove-ADGroupMember -id $groupname -members $user -confirm:$false
}
		

Office 365

Office 365 вездесущ, поэтому подключения это важные повседневные действия для администраторов. Вы можете применять vsadmin или отдельные функции.

Операции:

  • LaunchEOL/RemoveEOL (Exchange Online)

  • LaunchSOL/RemoveSOL (Skype online)

  • LaunchSPO/RemoveSPO (SharePoint online)

  • LaunchCOL/RemoveCOL (Security and Compliance)

  • LaunchMSOL/RemoveMSOL (MS Online Azure Active Directory)


##################Exchange Modern Online##################
Function LaunchEOL {
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $false)]
    $Credential
  )
  Import-Module ExchangeOnlineManagement -Prefix "EOL"
  Connect-ExchangeOnline -Prefix "EOL" -Credential $Credential -ShowBanner:$false
}
Function RemoveEOL {
  Disconnect-ExchangeOnline -Confirm:$false
}
#############Skype Online#####################################
function LaunchSOL
{
  param
  (
    [Parameter(Mandatory = $true)]
    $Domain,
    [Parameter(Mandatory = $false)]
    $Credential
  )
  Write-Host -Object "Enter Skype Online Credentials" -ForegroundColor Green
  $dommicrosoft = $domain + ".onmicrosoft.com"
  $CSSession = New-CsOnlineSession -Credential $Credential -OverrideAdminDomain $dommicrosoft
  Import-Module (Import-PSSession -Session $CSSession -AllowClobber) -Prefix SOL  -Global
} #Function LaunchSOL
Function RemoveSOL
{
  $Session = Get-PSSession | Where-Object -FilterScript { $_.ComputerName -like "*.online.lync.com" }
  Remove-PSSession $Session
} #Function RemoveSOL
############Sharepoint Online###############################
function LaunchSPO
{
  param
  (
    [Parameter(Mandatory = $true)]
    $orgName,
    [Parameter(Mandatory = $false)]
    $Credential
  )
  Write-Host "Enter Sharepoint Online Credentials" -ForegroundColor Green
  Connect-SPOService -Url "https://$orgName-admin.sharepoint.com" -Credential $Credential
} #LaunchSPO
Function RemoveSPO
{
  disconnect-sposervice
} #RemoveSPO
####Secuirty and Compliance#####################################
Function LaunchCOL {
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $false)]
    $Credential
  )
  Import-Module ExchangeOnlineManagement
  Connect-IPPSSession -Credential $Credential
  $s=Get-PSSession | where {$_.ComputerName -like "*compliance.protection.outlook.com"}
  Import-Module (Import-PSSession -Session $s  -AllowClobber) -Prefix col -Global
}
Function RemoveCOL {
  Disconnect-ExchangeOnline -Confirm:$false
}
###############################Msonline######################
function LaunchMSOL {
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory = $false)]
    $Credential
  )
  import-module msonline
  Write-Host "Enter MS Online Credentials" -ForegroundColor Green
  Connect-MsolService -Credential $Credential
}
Function RemoveMSOL {
  Write-host "Close Powershell Window - No disconnect available" -ForegroundColor yellow
}
#######################################################
		

Отчёт Почтового ящика Exchange Online

Теперь воспользуемся приводимой выше функцией для запуска оболочки Exchange Online. В PowerShell наберите LaunchEOL и снабдите свой Exchange Online идентификатором пользователя/ паролем администратора. После того как вы подключитесь к Exchange Online, для выделения отчётов почтовых ящиков из Office 365 воспользуйтесь следующей командой, которую вы можете видеть на Рисунке 10-5).

 

Рисунок 10-5


Отображение подключения в оболочке Exchange


Get-EOLMailbox -ResultSize unlimited | Select Name,Recipient TypeDetails,PrimarySMTPAddress,UserPrincipalName,litigationhold enabled,LitigationHoldDuration,PersistedCapabilities,Retention HoldEnabled,RetentionPolicy,RetainDeletedItemsFor,ArchiveName, Archivestatus,ProhibitSendQuota,ProhibitSendReceiveQuota,MaxSend Size,MaxReceiveSize,AuditEnabled | export-csv c:\auditmbx.csv -notypeinfo
		

Когда у вас большое число арендаторов, воспользуйтесь приводимым кодом вместо указанного, поскольку этот не будет дросселироваться даже с более чем 50 000 пользователей:


$allmbx=Invoke-Command -Session (Get-PSSession | Where-Object{$_.computerName -eq "outlook.office365.com"}) -scriptblock {Get-Mailbox -ResultSize unlimited | Select-object Name,RecipientTypeDetails, PrimarySMTPaddress,UserPrincipalname,AuditEnabled,litigationholdenabled,LitigationHoldDuration,PersistedCapabilities,RetentionHoldEnabled,RetentionPolicy,RetainDeletedItemsFor,ArchiveName,Archivestatus,ArchiveGuid,ProhibitSendQuota,ProhibitSendReceiveQuota,MaxSendSize,MaxReceiveSize,WhenMailboxCreated,WhenCreated,HiddenFromAddressListsEnabled }
 $allmbx | export-csv c:\data\auditmbx.csv -notypeinfo
		

Отслеживание сообщения Exchange Online

В Exchange Online отслеживание выделения сообщений не точно такое же, что и в Exchange на площадке, потому как если получаемые результаты имеют большее число, тогда их нельзя выделять при помощи результата с безразмерным параметром. Ниже приводится небольшой сценарий, который проделывает подобный трюк:


$index = 1
while ($index -le 1001)
{
Get-EOLMessageTrace -SenderAddress "VikasS@techWizard.cloud" -StartDate 09/20/2019 -EndDate 09/25/2019 -PageSize 5000 -Page $index | export-csv c:\messagetracking.csv -Append
$index ++
sleep 5
}
		

Поиск унифицированного журнала

Office 365 применяет унифицированное ведение регистрации аудита и вы можете осуществлять аудит всех своих действий с применением оболочки Exchange Online (будь то SharePoint Online или Teams, либо любой иной продукт внутри Office 365). Вот ссылка для дополнительных подробностей: https://docs.microsoft.com/en-us/microsoft-365/compliance/search-the-audit-log-in-security-and-compliance%253FWT.mc_id%253DM365-MVP-5001317

Пример выделения действий Microsoft Teams:


Search-EOLUnifiedAuditLog -StartDate 1/8/2019 -EndDate 4/7/2019 -RecordType MicrosoftTeams -UserIds VikasS@sycloudpro.com  -ResultSize:5000 |export-csv c:\VikasS.csv -notypeinfo
		

Пример выделения аудита действий почтового ящика Exchange:


Search-EOLUnifiedAuditLog -StartDate 10/24/2019 -EndDate 10/25/2019 -UserIds VikasS@syscloudpro.com -recordtype "ExchangeItemGroup","ExchangeItem","ExchangeAggregatedOperation" -ResultSize:5000 |export-csv c:\VikasS.csv -notypeinfo
		

Пример добавления или удаления участника роли:


Search-EOLUnifiedAuditLog -StartDate 4/16/2019 -EndDate 7/15/2019 -UserIds VikasS@syscloudpro.com -operations "Add role member to role" -ResultSize:5000 |export-csv c:\VikasS.csv -notypeinfo
		

Azure AD

Я рассмотрел практические примеры Active Directory, однако в мире наших дней Azure AD становится распространённым, поэтому вот некоторые образцы из мира Azure AD.

Для Azure AD вам потребуется вначале для подключения применять connect-AzureAD, а для MS Online вы можете воспользоваться Connect-MsolService. После соединения, вы будете способны воспользоваться приводимыми далее примерами обновляя соответствующие переменные.

Добавление пользователей в группу Azure AD из текстового файла UPN


$group1 = "93345231-7454-4629-943b-e4245426bf" #
Get-Content C:\users.txt | ForEach-Object{$user=$_.trim();$user;$upn= $user
$getazureaduser = Get-AzureADUser -Filter "userprincipalname eq '$($upn)'"
 Add-AzureADGroupMember -ObjectId $group1  -RefObjectId $getazureaduser.ObjectId
}
		

Удаление пользователей в группе Azure AD из текстового файла UPN


$group1 = "93345231-7454-4629-943b-e4245426bf" #
Get-Content C:\users.txt | ForEach-Object{$user=$_.trim();$user;$upn= $user
$getazureaduser = Get-AzureADUser -Filter "userprincipalname eq '$($upn)'"
Remove-AzureADGroupMember -ObjectId $group1  -MemberId $getazureaduser.ObjectId
}
		

Проверка является ли пользователь участником группы


$group1 = "93345231-7454-4629-943b-e4245426bf" #
$getazmembership = Get-AzureADUserMembership  -ObjectId "UserObjectId"
if($getazmembership.objectId -contains $group1){
write-host  "User is already member of the group group1"
}
		

Добавление в роль Администраторов


Get-MsolRole | Sort Name | Select Name,Description #check role name
$roleName = "Lync Service Administrator"
Get-content c:\users.txt | foreach-object{$_;
Add-MsolRoleMember -RoleMemberEmailAddress $_ -RoleName $roleName
}
		

Проверка ошибок предоставления пользователей Azure AD


Get-MsolUser -HasErrorsOnly | ft DisplayName,UserPrincipalName,@{Name="Error";Expression={($_.errors[0].ErrorDetail.objecterrors.errorrecord.ErrorDescription)}} -AutoSize
		

Аналогичным образом вы можете подключаться к любому продукту Microsoft, сверившись с его документацией. Что касается прочих продуктов Azure, для подключения к Azure существует команда Connect-AzAccount. Просто убедитесь что в вашей машине установлены соответствующие модули для тех продуктов, к которым вы желаете подключаться.

Операции с файлом Text/CSV

Удаление имеющейся строки заголовка из файла CSV

Метод 1:


Get-Content .\abc.csv | select -skip 1 | Set-Content .\abc1.csv
		

Метод 2:


$a = import .\abc.csv
$a |ForEach-Object{
  $Con_string = $null
  $Con_string = $_.ID, $_.GrpName -join ','
  Write-Host $Con_string
  Add-Content .\abc6.csv $Con_string
}
		

Метод 3 (за исключением CRLF):


$text = [System.IO.File]::ReadAllText("$pwd\file.csv") -replace '^[^\r\n]*\r?\n'
[System.IO.File]::WriteAllText("$pwd\newFile.csv", $text)
		

Метод 4 (за исключением CRLF):


$file = Get-Item .\example_test.csv
$reader = $file.OpenText()
# discard the first line
$null = $reader.ReadLine()
# Write the rest of the text to the new file
[System.IO.File]::WriteAllText("$pwd\newFile.csv", $reader.ReadToEnd())
$reader.Close()
		

Добавление строки заголовка в текстовый файл:

Например, у вас имеется список идентификаторов работников в текстовом файле:


14562
67578
65888

$filep = "c:\file.txt"
$getNetworkID = Get-Content $filep | where { $_ -ne "" }
@("Employeeid") +  $getNetworkID | Set-Content  $filep -Force #add emplyeeidheader
 	   

Regex

Существуют ситуации, при которых вам для выполнения внутри своих сценариев операций установления соответствия требуется воспользоваться regex.

[Совет]Совет

Для проверки любого regex перед его применением вы можете воспользоваться https://regex101.com/.

Вот как вы можете применять его в PowerShell и это будет в основном использоваться с операторами match. Смотрите Рисунок 10-6 и Рисунок 10-7.


$regexemail = "^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
"sukhijav@techwizard.cloud" -match $regexemail
		
 

Рисунок 10-6


Отображение проверки регулярного выражения

 

Рисунок 10-7


Отображение операции регулярного выражения в PowerShell

Таблица 10-1. Шпаргалки регулярных выражений
Шпаргалка Regex Комментарий

1

Receipt_[0-9][0-9][0-9][0-9][0-9][0-9][0-9]\.doc

Содержит Reciept_7didgitnumber.doc

2

(Tickets issued to)(.*)(for travel)

Выпущенные для Vikas Sukhija билеты на путешествие

3

(.*)Aborted_payment_(.*)

Сообщите aborted_payment_(Y075958)

4

(.*)(\([A-Z][0-9][0-9][0-9][0-9][0-9][0-9])\)

(Y782714)

5

(.*)[0-9]{2}[A-Z]{1}[0-9]{6}

Critical_alert_-_36B881478

6

(?<=V0)(.*)(?=a)

V01234a

7

^\d+$

Для поиска целого

8

^0+$

Для поиска целого с 000000

9

^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

Для адреса электронной почты

Выводы

Это последняя глава данной книги и она была о том, как вы можете сочетать различные фрагменты кода и составлять сценарий, который способен выполнять кучу дел. Я делюсь различными примерами продуктов, которые можно применять системным администраторам в их повседневной деятельности. Дополнительные сценарии и сотни примеров доступны в https://techwizard.cloud/downloads/.