Skip to content

Commit

Permalink
feat(machine-offboarding): ✨ Added Remove-MdeMachine function
Browse files Browse the repository at this point in the history
  • Loading branch information
itpropro committed Nov 24, 2022
1 parent d5d2ad1 commit fa5d8e4
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 56 deletions.
47 changes: 47 additions & 0 deletions src/public/Remove-MdeMachine.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<#
.SYNOPSIS
Offboard device from Defender for Endpoint.
.DESCRIPTION
Offboard device from Defender for Endpoint.
.NOTES
Author: Jan-Henrik Damaschke
.LINK
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/offboard-machine-api?view=o365-worldwide
.PARAMETER id
Specifies the id of the target MDE machine.
.PARAMETER comment
Comment to associate with the action.
.EXAMPLE
Remove-MdeMachine -id "MACHINE_ID" -comment "Your comment"
.ROLE
@(@{permission = 'Machine.Offboard'; permissionType = 'Application'}, @{permission = 'Machine.Offboard'; permissionType = 'Delegated'})
#>

function Remove-MdeMachine {
[CmdletBinding()]
param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)]
[string]
$id,
[Parameter(Mandatory)]
[string]
$comment
)
Begin {
if (-not (Test-MdePermissions -functionName $PSCmdlet.CommandRuntime)) {
$requiredRoles = (Get-Help $PSCmdlet.CommandRuntime -Full).role | Invoke-Expression
Throw "Missing required permission(s). Please check if one of these is in current token roles: $($requiredRoles.permission)"
}
}
Process {
return Invoke-RetryRequest -Method Post -Uri "https://api.securitycenter.microsoft.com/api/machines/$id/offboard" -body (ConvertTo-Json -InputObject @{ Comment = $comment })
}
End {}
}
117 changes: 61 additions & 56 deletions src/public/Update-MdeMachine.ps1
Original file line number Diff line number Diff line change
@@ -1,59 +1,64 @@
<#
.SYNOPSIS
Updates properties of existing Machine.
.DESCRIPTION
Updates properties of existing Machine.
.NOTES
Author: Jan-Henrik Damaschke
.LINK
https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/update-machine-method?view=o365-worldwide
.EXAMPLE
Update-MdeMachine -id '123' -tags @('tag-1', 'tag-2')
.EXAMPLE
Update-MdeMachine -id '123' -priority 'High'
.ROLE
@(@{permission = 'Machine.ReadWrite.All'; permissionType = 'Application'}, @{permission = 'Machine.ReadWrite'; permissionType = 'Delegated'})
#>

function Update-MdeMachine {
[CmdletBinding()]
param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)]
[string]
$id,
[Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline)]
[array]
$tags,
[Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline)]
[ValidateSet('Low', 'Normal', 'High')]
[string]
$priority
)
Begin {
if (-not (Test-MdePermissions -functionName $PSCmdlet.CommandRuntime)) {
$requiredRoles = (Get-Help $PSCmdlet.CommandRuntime -Full).role | Invoke-Expression
Throw "Missing required permission(s). Please check if one of these is in current token roles: $($requiredRoles.permission)"
}
}
Process {
$body = @{}
if ($tags) { $body.machineTags = $tags }
if ($priority) { $body.deviceValue = $priority }
if ($body.Keys.Count) {
$result = Invoke-RetryRequest -Method Patch -body (ConvertTo-Json -InputObject $body) -Uri "https://api.securitycenter.microsoft.com/api/machines/$id"
Write-Verbose "Updated $id with $($body.Keys)"
return $result
} else {
Throw "Neither tags nor priority parameter provided. Please provide at least one."
}
}
End {}
<#
.SYNOPSIS
Updates properties of existing Machine.
.DESCRIPTION
Updates properties of existing Machine.
.NOTES
Author: Jan-Henrik Damaschke
.LINK
https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/update-machine-method?view=o365-worldwide
.EXAMPLE
Update-MdeMachine -id '123' -tags @('tag-1', 'tag-2')
.EXAMPLE
Update-MdeMachine -id '123' -priority 'High'
.ROLE
@(@{permission = 'Machine.ReadWrite.All'; permissionType = 'Application'}, @{permission = 'Machine.ReadWrite'; permissionType = 'Delegated'})
#>

function Update-MdeMachine {
[CmdletBinding()]
param (
[Parameter(Mandatory, ParameterSetName = 'tags', ValueFromPipelineByPropertyName, ValueFromPipeline)]
[Parameter(Mandatory, ParameterSetName = 'priority', ValueFromPipelineByPropertyName, ValueFromPipeline)]
[Parameter(Mandatory, ParameterSetName = 'all', ValueFromPipelineByPropertyName, ValueFromPipeline)]
[string]
$id,
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'tags')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'all')]
[array]
$tags,
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'priority')]
[Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'all')]
[ValidateSet('Low', 'Normal', 'High')]
[string]
$priority
)
Begin {
if (-not (Test-MdePermissions -functionName $PSCmdlet.CommandRuntime)) {
$requiredRoles = (Get-Help $PSCmdlet.CommandRuntime -Full).role | Invoke-Expression
Throw "Missing required permission(s). Please check if one of these is in current token roles: $($requiredRoles.permission)"
}
}
Process {
$body = @{}
if ($tags) { $body.machineTags = $tags }
if ($priority) { $body.deviceValue = $priority }
if ($body.Keys.Count) {
$result = Invoke-RetryRequest -Method Patch -body (ConvertTo-Json -InputObject $body) -Uri "https://api.securitycenter.microsoft.com/api/machines/$id"
Write-Verbose "Updated $id with $($body.Keys)"
return $result
}
else {
Throw "Neither tags nor priority parameter provided. Please provide at least one."
}
}
End {}
}
# SIG # Begin signature block
# MIIVigYJKoZIhvcNAQcCoIIVezCCFXcCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
Expand Down
32 changes: 32 additions & 0 deletions tests/public/Remove-MdeMachine.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
BeforeAll {
Remove-Module PSMDE -Force -ErrorAction SilentlyContinue
Import-Module (Split-Path $PSCommandPath).replace('tests', 'src').Replace('public', 'PSMDE.psd1')
}

Describe "Remove-MdeMachine" {

It 'Should have the PSMDE module loaded' {
$module = Get-Module PSMDE
$module | Should -Not -BeNullOrEmpty
}

It 'Should have access to internal functions' {
InModuleScope PSMDE {
$iar = Get-Command Invoke-AzureRequest
$iar | Should -Not -BeNullOrEmpty
}
}

It 'Should correctly create the request uri' {
InModuleScope PSMDE {
Mock Invoke-RetryRequest { return @{uri = $uri; body = $body } }
Mock Test-MdePermissions { return $true }
$id = '12345'
$comment = 'Comment'
$body = ConvertTo-Json -Depth 5 -InputObject @{comment = $comment }
$result = Remove-MdeMachine -id $id -comment $comment
$result.uri | Should -Be "https://api.securitycenter.microsoft.com/api/machines/$id/offboard"
$result.body | Should -Be $body
}
}
}
32 changes: 32 additions & 0 deletions tests/public/Remove-MdeMachineTag.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
BeforeAll {
Remove-Module PSMDE -Force -ErrorAction SilentlyContinue
Import-Module (Split-Path $PSCommandPath).replace('tests', 'src').Replace('public', 'PSMDE.psd1')
}

Describe "Remove-MdeMachineTag" {

It 'Should have the PSMDE module loaded' {
$module = Get-Module PSMDE
$module | Should -Not -BeNullOrEmpty
}

It 'Should have access to internal functions' {
InModuleScope PSMDE {
$iar = Get-Command Invoke-AzureRequest
$iar | Should -Not -BeNullOrEmpty
}
}

It 'Should correctly create the request uri' {
InModuleScope PSMDE {
Mock Invoke-RetryRequest { return @{uri = $uri; body = $body } }
Mock Test-MdePermissions { return $true }
$id = '12345'
$tag = 'monitored'
$body = ConvertTo-Json -Depth 5 -InputObject @{ Value = $tag; Action = 'Remove' }
$result = Remove-MdeMachineTag -id $id -tag $tag
$result.uri | Should -Be "https://api.securitycenter.microsoft.com/api/machines/$id/tags"
$result.body | Should -Be $body
}
}
}
33 changes: 33 additions & 0 deletions tests/public/Update-MdeMachine.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
BeforeAll {
Remove-Module PSMDE -Force -ErrorAction SilentlyContinue
Import-Module (Split-Path $PSCommandPath).replace('tests', 'src').Replace('public', 'PSMDE.psd1')
}

Describe "Update-MdeMachine" {

It 'Should have the PSMDE module loaded' {
$module = Get-Module PSMDE
$module | Should -Not -BeNullOrEmpty
}

It 'Should have access to internal functions' {
InModuleScope PSMDE {
$iar = Get-Command Invoke-AzureRequest
$iar | Should -Not -BeNullOrEmpty
}
}

It 'Should correctly create the request uri' {
InModuleScope PSMDE {
Mock Invoke-RetryRequest { return @{uri = $uri; body = $body } }
Mock Test-MdePermissions { return $true }
$id = '12345'
$tags = @('monitored-a', 'monitored-b')
$priority = 'Normal'
$body = ConvertTo-Json -InputObject @{ machineTags = $tags; deviceValue = $priority }
$result = Update-MdeMachine -id $id -tags $tags -priority $priority
$result.uri | Should -Be "https://api.securitycenter.microsoft.com/api/machines/$id"
$result.body | Should -Be $body
}
}
}

0 comments on commit fa5d8e4

Please sign in to comment.