<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Undocumented Features</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/undocumentedfeatures/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/feed.xml</link>
    <description />
    <lastBuildDate>Fri, 26 Apr 2019 13:29:37 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Update to the Set-UPNWithMailAddress Script</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/update-to-the-set-upnwithmailaddress-script</link>
      <pubDate>Fri, 26 Apr 2019 09:29:37 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7365</guid>
      <description><![CDATA[I hadn't touched this one in a while, but a recent request from a customer had me checking in on...]]></description>
      <content:encoded><![CDATA[I hadn't touched this one in a while, but a recent request from a customer had me checking in on it.  I tidied it up (no one likes people staring at their dirty laundry), and updated the scripting to be more efficient.  One of the things I noticed about it is that I had run multiple Get- requests against the same object, so I reduced it to one, cutting the script's execution time like a hot samurai blade through butter.

I've also updated the logging to include the object GUID, which may make it easier to restore objects should you need to put things back where you found them...which leads to a good idea for another script update next week. ;-)

Check out the update at <a target="_blank" href="https://gallery.technet.microsoft.com/Set-Upn-With-Mail-Address-c4d0ee60" rel="noopener">https://gallery.technet.microsoft.com/Set-Upn-With-Mail-Address-c4d0ee60</a>.

Now you can have your users updated before your cup of coffee even cools down.]]></content:encoded>
    </item>
    <item>
      <title>DLP for Bitcoin Addresses</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/dlp-for-bitcoin-addresses</link>
      <pubDate>Fri, 26 Apr 2019 09:28:32 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7355</guid>
      <description><![CDATA[One of the up-and-coming combination phish-ransom attacks is to trick the mark into thinking that...]]></description>
      <content:encoded><![CDATA[One of the up-and-coming combination phish-ransom attacks is to trick the mark into thinking that you've got access to their data, and then get them to send money to a Bitcoin address to protect them from data leakage.  You can create a DLP rule in the Office 365 Security &amp; Compliance Center (or an Exchange Online transport rule) to try to combat this.

The regular expression we're going to work with is:
<pre>(bc1|[13])[a-km-zA-HJ-NP-Z1-9]{25,34}(\s|$|\.(?!\w))</pre>
This will match the standard BTC addresses (beginning with bc1 or a 1 or a 3), and then 25-34 alphanumeric characters excluding lookalikes (lowercase L, uppercase i, numeral 0 and uppercase o), followed by a space character (\s), the end-of-line ($), or a period (as long as it didn't have any characters immediately after it).

To configure the Security &amp; Compliance DLP sensitive information type, follow these steps.

Security &amp; Compliance Center
<ol>
 	<li>Launch a browser, navigate to <strong>protection.office.com</strong>, select <strong>Classifications </strong>and then select <strong>Sensitive info types</strong>.</li>
 	<li>Click <strong>+Create</strong>.
<img width="2310" height="1485" class="alignnone size-full wp-image-7774" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc1.png" /></li>
 	<li>Enter a name and description and click <strong>Next</strong>.
<img width="2527" height="1485" class="alignnone size-full wp-image-7776" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc2.png" /></li>
 	<li>Click +<strong>Add an element.</strong>
<img width="2527" height="1485" class="alignnone size-full wp-image-7778" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc4.png" /></li>
 	<li>Select <strong>Regular expression</strong> from the drop-down, and paste in the regular expression text.
<img width="2527" height="1485" class="alignnone size-full wp-image-7779" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc5.png" /></li>
 	<li>If you want to increase the sensitivity or confidence level, you may want to include supporting elements like <strong>btc </strong>or <strong>wallet</strong> keywords and click <strong>Next</strong>.
<img width="2527" height="1485" class="alignnone size-full wp-image-7780" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc6.png" /></li>
 	<li>Confirm and click <strong>Finish</strong>.
<img width="2527" height="1485" class="alignnone size-full wp-image-7781" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc7.png" /></li>
 	<li>Click <strong>Yes </strong>to test your pattern against a file.
<img width="2527" height="1485" class="alignnone size-full wp-image-7782" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc8.png" /></li>
 	<li>Create a file with the following content:
<pre>Send BTC payment to address:1JHJnnDp9A92XdjfYkHKyrJ3R99Q72K3X4</pre>
</li>
 	<li>Upload the file and click <strong>Test</strong>.
<img width="2527" height="1485" class="alignnone size-full wp-image-7783" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc9.png" /></li>
 	<li>Click <strong>Finish</strong>.
<img width="2527" height="1485" class="alignnone size-full wp-image-7784" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/btc10.png" /></li>
</ol>
Once you've created the Sensitive info type, you can use it in DLP policies and labels.]]></content:encoded>
    </item>
    <item>
      <title>Bulk Converting Office 365 Groups to Teams</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/bulk-converting-office-365-groups-to-teams</link>
      <pubDate>Fri, 26 Apr 2019 09:27:47 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7345</guid>
      <description><![CDATA[This week, while working with one of my peers, a request came in to bulk convert all Office 365...]]></description>
      <content:encoded><![CDATA[This week, while working with one of my peers, a request came in to <em>bulk convert all Office 365 groups to Microsoft Teams</em>.  In the Teams UI, you're only presented the choice to upgrade groups you own, one at a time, to Teams.

<em>Anything UI can do, scripting does better.  Scripting does everything better than UI.</em>

<em>No, it doesn't! [Yes, it does!] No, it doesn't! [Yes, it does!]</em>

I think we all know how I feel about this.

So, in order to make this magic work, you'll need to:
<ul>
 	<li>Microsoft Teams PowerShell Model (<strong>Install-Module MicrosoftTeams</strong>)</li>
 	<li>Connect to Exchange Online PowerShell</li>
 	<li>Connect to Teams (<strong>Connect-MicrosoftTeams</strong>)</li>
</ul>
<pre>$UnifiedGroups = Get-UnifiedGroup -ResultSize Unlimited
$Teams = Get-Team
foreach ($Group in $UnifiedGroups) 
{ If (!($Teams.GroupId -match $group.ExternalDirectoryObjectId)) 
     { 
     New-Team -Group $Group.ExternalDirectoryObjectId 
     }
}</pre>
Voila!]]></content:encoded>
    </item>
    <item>
      <title>Creating a Teams "New Channel" notification</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/creating-a-teams-new-channel-notification</link>
      <pubDate>Fri, 26 Apr 2019 09:27:00 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7335</guid>
      <description><![CDATA[One of my customers recently asked for a solution to checking a particular Microsoft Team multiple...]]></description>
      <content:encoded><![CDATA[One of my customers recently asked for a solution to checking a particular Microsoft Team multiple times a day for new channel additions.  In their organization, someone is responsible for creating a new channel every time new item for review is published, and then all of the communications, files, and data related to that item is stored in that particular time.

So, this seemed like a good time for some automation.

Building on this post I did a while ago for getting started with <a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/" rel="noopener">Azure Automation Runbooks</a>, we can modify the scripting and the module and come out with a solution pretty quickly.  Read through that quick, and then come back here.

Done?

So, interject these pieces in at the applicable points in time, and you're good to go.

[toc]
<h1>Getting Information on the Team you want to monitor</h1>
We don't supply a whole lot of detail in the Get-Team cmdlet.  We only expose the DisplayName and GroupID (guid) of an object.  In this script, what we're going to do is look at the channels for a team, check the description for a particular phrase or keyword, and if it doesn't exist, we're going to treat it as new.
<ol>
 	<li>To install the Teams module, launch an elevated PowerShell session and run <strong>Install-Module MicrosoftTeams </strong>to download and install it from the PowerShell Gallery.</li>
 	<li>Once you've installed the module, you can use the <strong>Connect-MicrosoftTeams</strong> cmdlet to connect to your Office 365 tenant.</li>
 	<li>In order to get the information for the team whose channels we want to monitor, we'll need the object ID.  Run the <strong>Get-Team</strong> cmdlet, and then note the GroupID.
<img width="1568" height="559" class="alignnone size-full wp-image-7762" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel00.png" /></li>
</ol>
<h1>Configuring Azure Automation for Microsoft Teams</h1>
<ol>
 	<li><a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/#Create_an_Office_365_Service_Account" rel="noopener">Create an Office 365 Service Account that will be used to log in and run the services</a>.  If you want this account to send mail, it will need an Exchange Online mailbox license assigned.</li>
 	<li>Launch the Azure Portal, and <a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/#Create_an_Azure_Automation_Account" rel="noopener">create an Azure Automation service account</a>.</li>
 	<li>Under Shared Resources, click <strong>Modules,</strong> click <strong>Browse</strong> <strong>gallery</strong>.
<img width="2506" height="1805" class="alignnone size-full wp-image-7754" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel01.png" /></li>
 	<li>Search for <strong>Teams</strong> and select it.
<img width="2506" height="1805" class="alignnone size-full wp-image-7755" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel02.png" /></li>
 	<li>Click <strong>Import</strong>.
<img width="634" height="456" class="alignnone wp-image-7756" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel03.png" /></li>
 	<li>Click <strong>OK </strong>to acknowledge.
<img width="2506" height="1805" class="alignnone size-full wp-image-7757" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel04.png" /></li>
 	<li>Hopefully, you are blessed with an <strong>Import Successful</strong> toast notification.  If it doesn't, do not pass go and do not collect $200.
<img width="2506" height="1805" class="alignnone size-full wp-image-7758" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel05.png" /></li>
 	<li><a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/#Add_a_Credential" rel="noopener">Add a credential</a> (it'll be the credentials of the service account that you created in step 1).  Pay attention to the <strong>*Name</strong> value, as that's what we'll reference later on in the script.
<img width="2506" height="1805" class="alignnone size-full wp-image-7759" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel06.png" /></li>
 	<li>Prepare your script.  In normal Windows PowerShell scripting, you may be familiar with the Get-Credential cmdlet, which gives you the ability to request and store a credential object (so aptly named).  In PowerShell Runbooks, we're going to use the Azure Automation version of this cmdlet (Get-AutomationPSCredential).  When we use it, we're going to tell it which Azure Automation credential to use (using the value in the name parameter specified earlier).
$Credential = Get-AutomationPSCredential -Name "O365Service"</li>
 	<li>Under <strong>Process Automation, </strong>click <strong>Create a runbook</strong>.  You can see an overview of the process <a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/#Create_a_PowerShell_Runbook" rel="noopener">here</a>.
<img width="2506" height="1805" class="alignnone size-full wp-image-7760" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel08.png" /></li>
 	<li>Fill out the RunBook properties and click <strong>Create</strong>.
<img width="2506" height="1805" class="alignnone size-full wp-image-7761" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel09.png" /></li>
 	<li>Paste the script content in the runbook and click <strong>Test pane </strong>to try it out.
I've highlighted the areas you'll want to update:
<img width="2506" height="1805" class="alignnone size-full wp-image-7763" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel10.png" />
<div>
<pre>$Credential = Get-AutomationPSCredential -Name "<strong>O365Service</strong>"
Connect-MicrosoftTeams -Credential $Credential
$GroupId = "<strong>&lt;Group ID from above&gt;</strong>"
$NewChannels = Get-TeamChannel -GroupId $GroupId | ? { ($_.Description -eq $null -or $_.Description -notlike "<strong>*RunBook*</strong>") -and $_.DisplayName -ne "General" }
$SmtpServer = "smtp.office365.com"
$SmtpPort = "587"
$To = "<strong>recipient@domain.com</strong>"
$From = "<strong>sender@domain.com</strong>"
foreach ($Channel in $NewChannels)
{
    $Date = Get-Date -Format "yyyy-MM-dd HH:MM:ss"
    If ($Channel.Description) { $Description = $Channel.Description + " <strong>Processed via RunBook at $($Date)</strong>" }
    Else { $Description = "<strong>Processed via RunBook at $($Date)</strong>" }
    Set-TeamChannel -GroupId $GroupId -CurrentDisplayName $Channel.DisplayName -Description $Description
    Send-MailMessage -UseSsl -Port 587 -Credential $Credential -SmtpServer $smtpserver -To $To -From $From -Subject "New channel $($Channel.DisplayName) has been added. Go take a look!"
}
Disconnect-MicrosoftTeams</pre>
</div></li>
 	<li>Click <strong>Start.
</strong><img width="2506" height="1805" class="alignnone size-full wp-image-7764" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel11.png" /></li>
 	<li>Wait for the test to complete and review the output.
<img width="2506" height="1805" class="alignnone size-full wp-image-7765" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/04/teamchannel121.png" /></li>
 	<li><a target="_blank" href="https://www.undocumented-features.com/2019/01/31/getting-around-the-basics-of-azure-automation-for-office-365/#Set_It_and_Forget_It" rel="noopener">Publish it.</a></li>
</ol>
Once you have your schedule set, you'll begin receiving notifications on a regular basis for Team Channel additions.]]></content:encoded>
    </item>
    <item>
      <title>Hashmaker, Hashmaker, Make Me A Hash</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/hashmaker-hashmaker-make-me-a-hash</link>
      <pubDate>Fri, 26 Apr 2019 09:26:03 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7325</guid>
      <description><![CDATA[While contemplating methods to determine whether a file had changed or been updated, I thought that...]]></description>
      <content:encoded><![CDATA[While contemplating methods to determine whether a file had changed or been updated, I thought that an MD5 check would be a pretty simple way to figure out if something was different.

But what if I wanted to check bunches of stuff on the fly? Or download a file from a website and store it in memory and check it against an existing file? So many things rushed in, and I knew I had to take a break and figure this one out.

So, I thought: well, I could use Get-FileHash.  That's all well and good, and it <em>does indeed</em> generate an MD5 hash of a file.  However, Get-FileHash has a significant drawback for my purposes (hint: it's in the name).

That's right--it can only compute the hash of a <em>file</em>.  It can't do something like compute the hash of a string stored in memory.

<img width="982" height="720" class="alignnone size-full wp-image-7744" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/get-hash-01.jpg" />

Don't worry, Wanda--I've got a plan.

Save this as a .ps1, and dot-source it (. .\scriptname.ps1), and then you'll be right as rain:
<pre>Function Get-Hash([String[]] $StringValue,[ValidateSet('SHA','SHA1','MD5','SHA256','SHA384','SHA512')]$Algorithm = "MD5") 
{
$HashedValue = New-Object System.Text.StringBuilder 
[System.Security.Cryptography.HashAlgorithm]::Create($Algorithm).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($StringValue))|%{ 
[Void]$HashedValue.Append($_.ToString("x2")) 
} 
$HashedValue.ToString() 
}</pre>
Then, when you need to compute a hash of content stored in memory, simple run Get-Hash against it:
<pre>PS C:\temp&gt; $String = "Hello, World!"
PS C:\temp&gt; $String | Out-File hello.txt
PS C:\temp&gt; $SecondString = Get-Content hello.txt
PS C:\temp&gt; $Download = (New-Object System.Net.WebClient).DownloadString("https://www.undocumented-features.com/wp-content/uploads/2019/03/Hello.txt").Trim()
PS C:\temp&gt; Get-Hash $String
65a8e27d8879283831b664bd8b7f0ad4
PS C:\temp&gt; Get-Hash $SecondString
65a8e27d8879283831b664bd8b7f0ad4
PS C:\temp&gt; Get-Hash $Download
65a8e27d8879283831b664bd8b7f0ad4
PS C:\temp&gt;</pre>
<img width="2147" height="420" class="alignnone size-full wp-image-7746" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/get-hash-02.png" />

Voila! You can use the <strong>Algorithm</strong> parameter to compute hashes using different hash algorithms as well.  MD5 is the default that I set--though you're welcome to change it for your own purpsoes.

Now that we've found the hash--where's the beef?]]></content:encoded>
    </item>
    <item>
      <title>Update to the AAD Network Testing Tool</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/update-to-the-aad-network-testing-tool</link>
      <pubDate>Fri, 26 Apr 2019 09:25:07 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7315</guid>
      <description><![CDATA[Hey, all!  One AAD tool update deserves another!

Every so often, I check in to make sure I'm...]]></description>
      <content:encoded><![CDATA[Hey, all!  One AAD tool update deserves another!

Every so often, I check in to make sure I'm keeping the AAD Connect Network Test Tool as fresh as I can.  I've made a few changes to the way it works (hopefully which you all think is for the better).  One of the changes that I made on another tool recently was manipulating $PSBoundParameters to set some defaults, and I decided to pull that change into here as well:
<pre><span>If</span><span> (</span><span>$AllTests</span><span>)
{
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"AzureCredentialCheck"</span><span>)) { </span><span>$AzureCredentialCheck</span> <span>=</span> <span>$true</span><span> }
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"Dns"</span><span>)) { </span><span>$Dns</span> <span>=</span> <span>$true</span><span> }
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"Network"</span><span>)) { </span><span>$Network</span> <span>=</span> <span>$true</span><span> }
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"OnlineEndPoints"</span><span>)) { </span><span>$OnlineEndPoints</span> <span>=</span> <span>$true</span><span> }
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"ActiveDirectory"</span><span>)) { </span><span>$ActiveDirectory</span> <span>=</span> <span>$true</span><span> }
    </span><span>If</span><span> (</span><span>!</span><span>$PSBoundParameters</span><span>.ContainsKey(</span><span>"SystemConfiguration"</span><span>)) { </span><span>$SystemConfiguration</span> <span>=</span> <span>$true</span><span> }
}</span></pre>
So, what I did was add a new switch parameter called AllTests.  If the AllTests switch is called, then I'm going to use it to turn on all the individual test parameters.  Running <strong>-AllTests</strong> is functionally equivalent to running <strong>-AzureCredentialCheck -Dns -Network -OnlineEndPoints -ActiveDirectory -SystemConfiguration</strong>.  One of the benefits of doing it this way is that you can <em><strong>combine</strong></em><strong> </strong>the <strong>AllTests</strong> parameter <em>with</em> an individual test parameter to exclude a certain test.

For example, <strong>-AllTests -Dns:$false</strong> will run all tests except Dns.  Pretty nifty.

At any rate, in addition to that change, I've updated the endpoints list and put some error handling around the Resolve-DnsName cmdlets that the script uses.  I ran into a use case where the network was timing out, and it spit back some unsightly errors to the screen.  I don't like when someone calls my baby ugly, and I also don't like showing my baby being ugly.  Green is good.  Red is bad.

The completed result is pretty again:

<img width="2706" height="1786" class="alignnone size-full wp-image-7738" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/aadnetwork-2019-01.png" />

I fixed a few extra little pieces as well--such as instances when the Azure AD credential check wouldn't run, and making the -AllTests parameter on by default if no other parameters were specified.

You can get the updated tool at <a href="https://aka.ms/aadnetwork">https://aka.ms/aadnetwork</a>. Cheers!]]></content:encoded>
    </item>
    <item>
      <title>Update to the AAD Connect Advanced Permissions tool</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/update-to-the-aad-connect-advanced-permissions-tool-5</link>
      <pubDate>Fri, 26 Apr 2019 09:24:08 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7305</guid>
      <description><![CDATA[It's been a while since I've updated this popular tool, and the need was brought to my attention by...]]></description>
      <content:encoded><![CDATA[It's been a while since I've updated this popular tool, and the need was brought to my attention by a peer who noticed an attribute being exported to on-premises AD (but failing):

<img width="1586" height="492" class="alignnone size-full wp-image-7730" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/keycredentiallink-1-1.jpg" />As it turns out, the <a href="https://docs.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-hybrid-cert-whfb-settings-dir-sync">msDS-KeyCredentialLink is required for Windows Hello for Business Hybrid.</a>

I've updated the permissions tool to handle the msDS-KeyCredentialLink attribute (which is used in Windows Hello for Business).  I'm sure there are some weird edge cases, so I've not only added the user to the Key Admins group, but I have also delegated RP and WP on the objects directly (I'm a belt and suspenders kind of guy).

<img width="2003" height="518" class="alignnone size-full wp-image-7731" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/keycredentiallink-2.png" />

Go grab the new version at <a href="https://aka.ms/aadpermissions">https://aka.ms/aadpermissions</a>.]]></content:encoded>
    </item>
    <item>
      <title>Update to Get-SCCDataExport</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/update-to-get-sccdataexport</link>
      <pubDate>Fri, 26 Apr 2019 09:22:14 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7295</guid>
      <description><![CDATA[I've been tinkering around a little with this, hoping to bring some better updates (so maybe you can...]]></description>
      <content:encoded><![CDATA[I've been tinkering around a little with this, hoping to bring some better updates (so maybe you can see who is generating your data exports and go smack them around).

I've got a few updated fields added to the tool, so be sure to go check it out!

<img width="2854" height="601" class="alignnone size-full wp-image-7734" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/03/getsccdataexport-2.png" />

Since the object is exported to the console, remember, you can do WHATEVER YOU WANT TO with it, like:
<pre>$Exports | ? { $_.ExportedBytes -gt 0 } 
$SummaryByUser = $Exports | Group-Object -Property CreatedBy
$Exports | ? { $_.StartTime -gt (Get-Date).AddDays(-14) }</pre>
Here's the link: <a href="https://gallery.technet.microsoft.com/Get-SCCExportDataSize-1dc80e88">https://gallery.technet.microsoft.com/Get-SCCExportDataSize-1dc80e88</a>]]></content:encoded>
    </item>
    <item>
      <title>WhoAmI for Office 365</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/whoami-for-office-365</link>
      <pubDate>Thu, 21 Feb 2019 16:30:55 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7285</guid>
      <description><![CDATA[If you've ever struggled to find out who your current session is logged in as when you connected to...]]></description>
      <content:encoded><![CDATA[If you've ever struggled to find out <em>who</em> your current session is logged in as when you connected to Office 365, here's a tidbit to shed some light on it:

(Get-PSSession |?{$_.ComputerName -like "*outlook.com"})[0].RunSpace.ConnectionInfo.Credential.UserName

<img width="1725" height="261" class="alignnone size-full wp-image-7713" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/WhoAmI.png" />

You can also use RunSpace.<strong>OriginalConnectionInfo</strong>.Credential.UserName.  The <a href="https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.runspace?view=powershellsdk-1.1.0">SDK</a> says ConnectionInfo vs OriginalConnectionInfo:

<strong>ConnectionInfo</strong> - Connection information for remote Runspaces, null for local Runspaces

<strong>OriginalConnectionInfo </strong>- ConnectionInfo originally supplied by the user

I have found them to have the same output in the context of Office 365 to this point, but if any of my readers stumbles upon a difference, I'd be happy to learn!]]></content:encoded>
    </item>
    <item>
      <title>Calculating your Daily Export for the Security &amp; Compliance Center</title>
      <link>https://docs.microsoft.com/archive/blogs/undocumentedfeatures/calculating-your-daily-export-for-the-security-compliance-center</link>
      <pubDate>Thu, 21 Feb 2019 16:29:53 GMT</pubDate>
      <dc:creator><![CDATA[Aaron Guilmette]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/undocumentedfeatures/?p=7275</guid>
      <description><![CDATA[One of the lesser-known boundaries of Office 365's Security &amp; Compliance Center is that we only...]]></description>
      <content:encoded><![CDATA[One of the lesser-known boundaries of Office 365's Security &amp; Compliance Center is that we only allow 2TB per day <a href="https://docs.microsoft.com/en-us/office365/securitycompliance/export-search-results"><em><strong>export volume</strong></em></a>.  When we talk about exports, we're talking about the idea of taking content that has been identified via a content search mechanism (content search, eDiscovery case search, etc) and then <em>staged for download</em>.

After the search results are identified, during the export process, they are moved into Azure Blob Storage.  This is where the 2TB limit comes in.  You are limited to 2TB of content in a rolling 24-hour period (which you can, after some ticketing, get temporarily raised).

We don't provide a great mechanism in the UI to track and determine this, so for most customers, the way they learn about it is an error dialog box:

<img width="498" height="322" class="alignnone size-full wp-image-7704" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize1.png" />

Currently, you don't really know until you get there, which is kind of like listening to your parents give you a status update on a family roadtrip.

For customers who export a lot of data, this can be frustrating.  And, like I previously said, the UI doesn't give you a good way to summarize the cases and export volume.  B<span>ut THIS IS SPART--</span>

<img width="300" height="215" class="alignnone wp-image-7705 size-medium" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize1.5-300x215.jpg" />

Whoa.  Maybe not. Maybe it's just PowerShell, but it's still pretty good.

Using the Compliance cmdlets, we can get a little bit of insight into the what the status of exports is.

Running the script with no parameters (or with the <strong>-Report </strong>parameter) is the same as running it with <strong>-SearchType SearchByRecentOnly -Hours</strong> <strong>24.</strong>  That means, we're looking for <em>cases</em> accessed in the last 24 hours, and then inside that, looking for <em>exports</em> performed in the last 24 hours.  The difference with <strong>-Report</strong>, of course, is that you get a report at the end.

<img width="2365" height="445" class="alignnone size-full wp-image-7706" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize2.png" />

The end result:

<img width="2365" height="277" class="alignnone size-full wp-image-7707" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize3.png" />

You'll see you have two pieces of information:
<ul>
 	<li>You have a report.</li>
 	<li>You have some exported objects.</li>
</ul>
The report is the same as the exported objects, so we'll go look in the $Exports object:

<img width="2365" height="436" class="alignnone size-full wp-image-7708" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize4.png" />

I've also included some additional parameters, such as searching <em>all cases</em> (which you'll want to do for looking for results exports further back) as well as looking at the <em>LastModifiedDateTime</em> stamp on the eDiscovery case object.  Fun fact: the LastModifiedDateTime property <em>is not</em> updated when you do work inside of the case--it's only updated when you make changes to the properties of the case object itself.

A final note: If you aren't a member of eDiscovery Case Admins, you'll only be able to see results for cases that you either own (created) or were made a member of by another case owner.

<img width="2365" height="373" class="alignnone size-full wp-image-7709" alt="" src="https://www.undocumented-features.com/wp-content/uploads/2019/02/Get-SCCExportDataSize5.png" />

You can download the script in the TechNet Gallery at: <a target="_blank" href="https://gallery.technet.microsoft.com/Get-SCCExportDataSize-1dc80e88" rel="noopener">https://gallery.technet.microsoft.com/Get-SCCExportDataSize-1dc80e88</a>

&nbsp;]]></content:encoded>
    </item>
  </channel>
</rss>