M365 OneDrive Discovery

M365SONE.OneDrive.POSH.Discovery.DS (DataSourceModuleType)

Will discover OneDrive objects.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsM365SL.RunAs.Profile
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelector
IntervalSecondsint$Config/IntervalSeconds$
PoshLibraryPathstring$Config/PoshLibraryPath$
ProbeActionTimeoutSecondsint$Config/ProbeActionTimeoutSeconds$
SyncTimestring$Config/SyncTime$
WriteToEventLogbool$Config/WriteToEventLog$

Source Code:

<DataSourceModuleType ID="M365SONE.OneDrive.POSH.Discovery.DS" Accessibility="Public" Batching="false" RunAs="M365SL!M365SL.RunAs.Profile">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ApiTokenScopeURL" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ApiTokenURL" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ApiURL" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" minOccurs="1" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MgmtGroupRegKey" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="PoshLibraryPath" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="PrincipalName" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ProbeActionTimeoutSeconds" minOccurs="1" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TenantName" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TLSVersion" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WorkflowName" minOccurs="1" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WriteToEventLog" minOccurs="1" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="PoshLibraryPath" Selector="$Config/PoshLibraryPath$" ParameterType="string"/>
<OverrideableParameter ID="ProbeActionTimeoutSeconds" Selector="$Config/ProbeActionTimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="WriteToEventLog" Selector="$Config/WriteToEventLog$" ParameterType="bool"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>M365SONE.OneDriveDiscovery.ps1</ScriptName>
<ScriptBody><Script>&lt;#
Filename: M365SONE.OneDriveDiscovery.ps1
Description: Will discovery entities from registry settings
Author: Tyson Paul
Blog: MonitoringGuys.com
Version History:
2020.11.18.2200 - Added API Url params
2020.10.07.1408 - Updated variable usage
2020.09.29.1128 - v1
#&gt;
########################################################################################################

Param (
[string]$ApiTokenScopeURL,
[string]$ApiTokenURL,
[string]$ApiURL,
[string]$ManagedEntityID = "No ManagedEntityID defined",
[string]$MgmtGroupRegKey,
[string]$PoshLibraryPath, #comma-separated list of .ps1 files to load
[string]$PrincipalName = "No PrincipalName defined!",
[string]$SkuNamesFilePath,
[string]$SourceID = "No SourceID defined",
[string]$TenantName,
[string]$TLSVersion,
[string]$WorkflowName = '&lt;No Name Provided&gt;',
[string]$WriteToEventLog="false"
)

[bool]$WriteToEventLog = [System.Convert]::ToBoolean($WriteToEventLog)
[string]$ScriptName = 'M365SONE.OneDriveDiscovery.ps1'
$NameSpace = 'OneDrive'
$Testing = $false
[string]$ScriptOutputType='DiscoveryData'

######################### FUNCTIONS ############################
################################################################
Function Load-Library {
Param (
[string]$PoshLibraryPath
)
$ErrorActionPreference = 'STOP'
If ($PoshLibraryPath ){
ForEach ($Path in $PoshLibraryPath.Split(',') ){
Try {
If (($Path.Length) -AND ($Path -notmatch '^-1$')) {
. $Path
}
} Catch {
Write-Host "Line [$($MyInvocation.ScriptLineNumber )]: Error loading PoshLibrary at path:[$($Path)]. This is likely to cause many other dependent functions to fail. `n`nError data: $($_)`n`n"
}
}
}
$ErrorActionPreference = 'CONTINUE'
}
################################################################

############## TESTING ##############
&lt;# #Run this as needed when testing

#---------------------------------------
Function Testing {
$Testing = $true
$testParamsFile = (Join-path $TestFolder ("PARAMS_$($ScriptName)"))
#Write-Host "$(Test-Path $testParamsFile):$($testParamsFile)" -F Yellow -B Green
. $testParamsFile
. Load-Library -PoshLibraryPath $PoshLibraryPath

# Encode user data/passwords in current test user context
$M365_ClientSecret = Encode-UserData $M365_ClientSecret_PLAINTEXT
$M365_AccountPassword = Encode-UserData $M365_AccountPassword_PLAINTEXT
$error.Clear()
}
#---------------------------------------

$TestFolder = "C:\Test\M365SMP_Dev\$($NameSpace)\TestSetup"
If (Test-Path -Path $TestFolder) {
. Testing
}
#&gt;
############## TESTING ##############


. Load-Library -PoshLibraryPath $PoshLibraryPath

LogIt -EventID 9990 -Type $info -Msg "Begin script..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()

LogIt -EventID 9992 -Type $info -msg "Setting TLS for session, Version: [$($TLSVersion)]." -Proceed $WriteToEventLog -Line $(_LINE_); $Error.Clear();
#Set Default TLS
. Set-TLS -TLSVersion $TLSVersion


$TenantKey = Join-Path $MgmtGroupRegKey $TenantName
$ThisKey = Join-Path $TenantKey $NameSpace
$TenantKeyPath = $TenantKey.Replace("HKLM\",'HKLM:\')
$RegKeyPath = $ThisKey.Replace("HKLM\",'HKLM:\')
LogIt -EventID 9992 -Type $info -Msg "TenantKeyPath: [$($TenantKeyPath)], KeyPath: [$($RegKeyPath)]" -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()

$api = New-Object -comObject 'MOM.ScriptAPI'
$discoveryData = $api.CreateDiscoveryData(0, $SourceID, $ManagedEntityID)

Try {
# Verify if the Reg key exists
If (Test-Path $RegKeyPath ) {
$RegProperties = (Get-ItemProperty -Path $RegKeyPath -ErrorAction Stop)
# Verify if properties exists (Data/Values)
If (-NOT [bool]$RegProperties) {
$discoveryData
LogIt -EventID 9995 -Type $warn -Msg "RegKey does exist:[$($ThisKey)] but no properties found. This is unusual; if the key exists, properties/data should exist also. Exiting Discovery workflow: [$WorkflowName]. " -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
}
}
Else {throw}
} Catch {
# Return empty discovery data. This will undiscover entities if they were previously discovered.
$discoveryData
LogIt -EventID 9992 -Type $info -Msg "RegKey does not exist:[$($ThisKey)] or possible error accessing registry data value(s). Exiting Discovery workflow: [$WorkflowName]. " -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
Exit
}

If ($Testing) {
$RegProperties.M365_AccountName = $M365_AccountName
$RegProperties.M365_ClientID = $M365_ClientId
$RegProperties.M365_AccountPassword = Encode-UserData -Data $M365_AccountPassword_PLAINTEXT
$RegProperties.M365_ClientSecret = Encode-UserData -Data $M365_ClientSecret_PLAINTEXT
}
Else {
$M365_AccountName = $RegProperties.M365_AccountName
$M365_ClientId = $RegProperties.M365_ClientID
$M365_AccountPassword = $RegProperties.M365_AccountPassword
$M365_ClientSecret = $RegProperties.M365_ClientSecret

}

# Decode Account Password
LogIt -EventID 9992 -Type $info -Msg "Decode password..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
Try {
$M365_AccountPassword_DECRYPTED = Decode-UserData -Data $M365_AccountPassword
} Catch {
LogIt -EventID 9995 -Type $warn -Msg "Unable to decode password. See error data. Exiting." -Proceed $true -LINE $(_LINE_); $Error.Clear()
Exit
}

# Decode Client Secret
LogIt -EventID 9992 -Type $info -Msg "Decode ClientSecret..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
Try {
$M365_ClientSecret_DECRYPTED = Decode-UserData -Data $M365_ClientSecret
} Catch {
LogIt -EventID 9995 -Type $warn -Msg "Unable to decode ClientSecret. See error data. Exiting." -Proceed $true -LINE $(_LINE_); $Error.Clear()
Exit
}

# Get Access Token
LogIt -EventID 9992 -Type $info -Msg "Get Access Token..." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
Try {
$TokenResponse = Get-AccessToken -Delegated -User $M365_AccountName -Pass $M365_AccountPassword_DECRYPTED -ClientID $M365_ClientID -ClientSecret $M365_ClientSecret_DECRYPTED -TenantName $TenantName -ApiTokenUrl $ApiTokenURL -ApiTokenScopeURL $ApiTokenScopeURL
} Catch {
LogIt -EventID 9995 -Type $warn -Msg "Unable to retrieve Access Token. See error data. Exiting." -Proceed $true -LINE $(_LINE_); $Error.Clear()
Exit
}

# Retrieve OneDrive object
LogIt -EventID 9992 -Type $info -Msg "Retrieve OneDrive object(s)" -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
Try {
$URL = "$($ApiURL)/v1.0/me/drive/root/"
[array]$Drive = Invoke-RestMethod -Headers @{Authorization = "Bearer $($TokenResponse.access_token)"} -Uri $URL -Method Get -ContentType 'application/json' -ErrorAction Stop
LogIt -EventID 9992 -Type $info -Msg "Retrieved object(s): [$($Drive.Name | Out-String)]" -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
} Catch {
LogIt -EventID 9995 -Type $warn -Msg "Unable to get object(s). See error data. Exiting." -Proceed $true -LINE $(_LINE_); $Error.Clear()
Exit
}

# Verify object exists
If (-NOT ($Drive.Count)) {
LogIt -EventID 9992 -Type $info -Msg "No objects exist. Will UNdiscover any registered objects. Exiting Discovery workflow: [$WorkflowName]. " -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
# Return empty discovery data. This will undiscover entities if they were previously discovered.
$discoveryData
Exit
}


#region BuildDiscovery
Try {
LogIt -EventID 9992 -Type $info -Msg "Properties exist at this Key: [$($ThisKey)]. Proceed to discover this class type: [M365SONE.OneDrive.Folder] for TenantName: [$($TenantName)]." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()

# Declare instance
$instance = $discoveryData.CreateClassInstance('$MPElement[Name="M365SONE.OneDrive.Folder"]$')

# Parent
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/IntervalSeconds$", [int]($RegProperties.IntervalSeconds ) )
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/M365_AccountName$", [string]($M365_AccountName ) )
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/M365_AccountPassword$", [string]($M365_AccountPassword ) )
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/M365_ClientID$", [string]($M365_ClientID ) )
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/M365_ClientSecret$", [string]($M365_ClientSecret ) )
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.M365ServiceComponent']/TenantName$", [string]($TenantName) )

# Add instance properties
$instance.AddProperty("$MPElement[Name='M365SONE.OneDrive.Folder']/ID$", ($Drive[0].ID) )
$instance.AddProperty("$MPElement[Name='M365SONE.OneDrive.Folder']/Name$", ($Drive[0].Name) )
$instance.AddProperty("$MPElement[Name='M365SONE.OneDrive.Folder']/WebURL$", ($Drive[0].WebURL) )
$instance.AddProperty("$MPElement[Name='M365SONE.OneDrive.Folder']/DriveType$", ($Drive[0].DriveType) )

# Host
$instance.AddProperty("$MPElement[Name='M365SL!M365SL.WatcherNode']/TenantName$", [string]($TenantName) )

# Standard Props
$instance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $PrincipalName)
$instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", ($Drive[0].WebURL) )

$discoveryData.AddInstance($instance)
LogIt -EventID 9992 -Type $info -Msg "Added discovery instance data for M365SONE.OneDrive.Folder name: [$($Drive[0].Name)], tenant: [$($TenantName)], WebURL: [$($Drive[0].WebURL)]." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
}
Catch {
$msg = "There was a critical failure in discovery for M365SONE.OneDrive.Folder name: [$($Drive[0].Name)], tenant: [$($TenantName)], WebURL: [$($Drive[0].WebURL)]."
LogIt -EventID 9995 -Type $Critical -Msg $msg -Proceed $true -LINE $(_LINE_); $Error.Clear()
}
#endregion

LogIt -EventID 9992 -Type $info -Msg "Return OneDrive discovery data for tenant: [$($TenantName)]." -Proceed $WriteToEventLog -LINE $(_LINE_); $Error.Clear()
$discoveryData

If ($Testing) {
$api.Return($discoveryData)
}

LogIt -EventID 9991 -Type $info -Msg "End script. Finished in [$($ScriptTimer.Elapsed.TotalSeconds)] seconds. `n" -LINE $(_LINE_)</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>ApiTokenScopeURL</Name>
<Value>$Config/ApiTokenScopeURL$</Value>
</Parameter>
<Parameter>
<Name>ApiTokenURL</Name>
<Value>$Config/ApiTokenURL$</Value>
</Parameter>
<Parameter>
<Name>ApiURL</Name>
<Value>$Config/ApiURL$</Value>
</Parameter>
<Parameter>
<Name>ManagedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>MgmtGroupRegKey</Name>
<Value>$Config/MgmtGroupRegKey$</Value>
</Parameter>
<Parameter>
<Name>PoshLibraryPath</Name>
<Value>$FileResource[Name='Res.M365SONE.M365Library.ps1.Resource']/Path$,$Config/PoshLibraryPath$</Value>
</Parameter>
<Parameter>
<Name>PrincipalName</Name>
<Value>$Config/PrincipalName$</Value>
</Parameter>
<Parameter>
<Name>SourceId</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>TenantName</Name>
<Value>$Config/TenantName$</Value>
</Parameter>
<Parameter>
<Name>TLSVersion</Name>
<Value>$Config/TLSVersion$</Value>
</Parameter>
<Parameter>
<Name>WorkflowName</Name>
<Value>$Config/WorkflowName$</Value>
</Parameter>
<Parameter>
<Name>WriteToEventLog</Name>
<Value>$Config/WriteToEventLog$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/ProbeActionTimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>