Начиная

Reporting Objects

Eventually, a script extracts all the required data and it’s time to generate some form of report. Some of the common ways to make the output generated by a script available to people include:

These actions mark the final stage of a script. Before a script can post, send, or store anything, the data retrieved from objects must be held in a PowerShell object, usually an array or a list.

I use the same approach to record data in all scripts. First, I create a PowerShell list:

$Report = [System.Collections.Generic.List[Object]]::new()

Then, after the script processes an object, the data to capture is handled by populating the properties of a custom object and writing it to the list. In performance terms, this approach is better than adding items to an array because PowerShell recreates the array for each addition. That’s OK for a couple of items but not so good when dealing with thousands. Updating the list is simple. For instance:

$ReportLine = [PSCustomObject]@{ TimeStamp = $M.Received Sender = $M.SenderAddress Recipient = $M.RecipientAddress Subject = $M.Subject Status = $M.Status Direction = $Direction SenderDomain = $SenderDomain RecipientDomain = $RecipientDomain }
$Report.Add($ReportLine)

The output list is easy to work with and easy to transform into other forms. For instance, to include the data in a HTML file, the script can convert the list like this:

$HTMLData = $Report | ConvertTo-HTML -Fragment

Filtering and Limits

[array]$Mailboxes = Get-ExoMailbox -Filter {Office -eq "Dublin"} -RecipientTypeDetails UserMailbox -ResultSize Unlimited
[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member' and OfficeLocation eq 'Dublin'" -ConsistencyLevel eventual -CountVariable Records -All

Nevertheless, the point remains that the golden rule is to only fetch the data you need to process. Using good filters is the best way to accomplish this goal.

:/>  Пишем вирус и антивирус

Lots More to Learn about Microsoft 365 PowerShell

Hopefully, you’ll find that the many Practical365.com articles we publish about using PowerShell to get real work done help. And if you want to browse code, feel free to look through my GitHub repository. You might even find some working code there.

Interpreting Objects

Once you’ve found some objects, the next step is to make sense of the data. Most PowerShell cmdlets return easy-to-use properties, but there are a few things to watch out for with some Microsoft 365 cmdlets.

In some cases, the value returned for a property is an array and some work is needed to get the full information that you might want. Consider this example of finding who manages a distribution list:

Get-DistributionGroup -Identity VIPusers | Format-List ManagedBy
ManagedBy : {tony.redmond, Lotte.Vetler, d36b323a-32c3-4ca5-a4a5-2f7b4fbef31c}

The ManagedBy property holds the name of each owner account. To get more information about the owners, use the names with another cmdlet like Get-ExoMailbox. For example:

[array]$ManagedBy = Get-DistributionGroup -Identity VIPUsers | Select-Object -ExpandProperty ManagedBy
$ManagedBy | Get-ExoMailbox | Format-Table DisplayName, Alias, Name
DisplayName Alias Name
----------- ----- ----
Tony Redmond Tony.Redmond tony.redmond
Lotte Vetler Lotte.Vetler Lotte.Vetler
Kim Akers (She/Her) Kim.Akers d36b323a-32c3-4ca5-a4a5-2f7b4fbef31c

Some of the Microsoft Graph PowerShell SDK cmdlets obscure valuable information. For example, the Get-MgGroupMember cmdlet returns a list of account identifiers for group members:

Get-MgGroupMember -GroupId (Get-MgGroup -Filter "Displayname eq 'System Innovation'").Id
Id DeletedDateTime
-- ---------------
eff4cd58-1bb8-4899-94de-795f656b4a18
a3eeaea5-409f-4b89-b039-1bb68276e97d
67105a51-e817-493e-8094-f600babf5f62
d36b323a-32c3-4ca5-a4a5-2f7b4fbef31c

If you want details of the group members, a different approach is necessary to retrieve the information from the additionalProperties property:

$GroupId = (Get-MgGroup -Filter "displayName eq 'System Innovation'").Id
Get-MgGroupMember -GroupId $GroupId | Select-Object -ExpandProperty additionalProperties
Key Value
--- -----
@odata.type #microsoft.graph.user
businessPhones {+1 713 633-5141}
displayName Kim Akers (She/Her)
givenName Kim
jobTitle VP Marketing
mail Kim.Akers@office365itpros.com
mobilePhone +1 761 504-0011
officeLocation NYC
preferredLanguage en-US
surname Akers
userPrincipalName Kim.Akers@office365itpros.com

Before you ask, it’s the Graph that returns data in this way.

:/>  Установка psm с использованием скриптов powershell

The unified audit log is a great source of valuable information about who did what and when inside a Microsoft 365 tenant. Workloads capture audit events as people interact with applications and those events eventually end up in the audit log. The Search-UnifiedAuditLog cmdlet (which has had some recent problems) finds data from the log. A lot of interesting detail is contained in a JSON-format property called AuditData. Before you can extract information from that property, you must convert it from JSON.

$Records = search-UnifiedAuditLog -StartDate 18-Oct-2023 -EndDate 19-Oct-2023 -Operations FileModified -Formatted -ResultSize 5000 -SessionCommand ReturnLargeSet

After finding the right event, we can convert its AuditData property:

$AuditData = $Records[0].AuditData | ConvertFrom-Json

And then all the fields in the property are available for use in a script. For instance, here’s the site URL for the modified document:

$AuditData.SiteUrl
https://office365itpros.sharepoint.com/sites/BlogsAndProjects/

At this point, you might wonder how to deal with all of the edge cases you might encounter. Trial and error and good internet searches are the normal response. Someone has probably met and overcome a problem you meet, and maybe there’s a Practical365.com article that helps. Just be persistent.

Начиная

Getting Objects

All the Microsoft 365 modules are well-equipped with cmdlets to fetch objects. Sometimes multiple cmdlets exist that can fetch the same objects, meaning that the trick is to make the right choice of which cmdlet to use. That decision depends on the context. We’ll get to that later.

Table 1 lists some of the basic objects used in Microsoft 365 and the cmdlets available to fetch these objects.

Object typeCmdletsModule
User accountsGet-MgUserMicrosoft Graph PowerShell SDK
MailboxesGet-Mailbox and Get-ExoMailboxExchange Online management
SharePoint Online sitesGet-SPOSite Get-MgSiteSharePoint Online management Microsoft Graph PowerShell SDK
OneDrive for Business accountsGet-SPOSite Get-MgSiteSharePoint Online management Microsoft Graph PowerShell SDK
Microsoft 365 GroupsGet-UnifiedGroup Get-MgGroupExchange Online management Microsoft Graph PowerShell SDK
TeamsGet-Team Get-MgTeamMicrosoft Teams Microsoft Graph PowerShell SDK
DevicesGet-MgDeviceMicrosoft Graph PowerShell SDK
Table 1: Cmdlets to fetch Microsoft 365 objects

Do Three Fundamentals of Microsoft 365 PowerShell Well and Scripting is Much Easier

As some of you might know, I write a lot of PowerShell. I’m not a very good PowerShell developer. Most of my code ignores fundamentals like error handling because I write scripts to explore and explain principles of getting work done rather than to develop complete solutions. In any case, that’s my excuse.

  • Get objects.
  • Interpret objects.
  • Report objects.
:/>  Программа svchost exe что это

Начиная