Skip to content

Commit

Permalink
Fixes and improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
homotechsual committed Nov 17, 2023
1 parent bc36491 commit 3f2e115
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 42 deletions.
7 changes: 5 additions & 2 deletions .build/CommandletShortNames.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Get-NinjaOneDeviceScriptingOptions: Device Scripting Options
Get-NinjaOneDeviceSoftwarePatches: Device Software Patches
Get-NinjaOneDeviceSoftwarePatchInstalls: Device Software Patch Installs
Get-NinjaOneDeviceVolumes: Device Volumes
Get-NinjaOneDeviceWindowsServices: Device Windows Services
Get-NinjaOneDisks: Disks Query
Get-NinjaOneGroupMembers: Group Members
Get-NinjaOneGroups: Groups
Expand Down Expand Up @@ -67,6 +68,7 @@ New-NinjaOneLocation: Location
New-NinjaOneOrganisation: Organisation
New-NinjaOnePolicy: Policy
New-NinjaOneTicket: Ticket
New-NinjaOneTicketComment: Ticket Comment
Remove-NinjaOneDeviceMaintenance: Maintenance
Remove-NinjaOneWebhook: Webhook
Reset-NinjaOneAlert: Alert
Expand All @@ -75,12 +77,13 @@ Restart-NinjaOneDevice: Device
Set-NinjaOneDevice: Device
Set-NinjaOneDeviceApproval: Device Approval
Set-NinjaOneDeviceCustomFields: Device Custom Fields
Set-NinjaOneDeviceMaintenance: Maintenance
Set-NinjaOneDeviceMaintenance: Device Maintenance
Set-NinjaOneLocation: Location
Set-NinjaOneLocationCustomFields: Location Custom Fields
Set-NinjaOneNodeRolePolicyAssignment: Node Role Policy Assignment
Set-NinjaOneOrganisation: Organisation
Set-NinjaOneOrganisationCustomFields: Organisation Custom Fields
Set-NinjaOneOrganisationDocument: Document
Set-NinjaOneOrganisationDocument: Organisation Document
Set-NinjaOneTicket: Ticket
Set-NinjaOneWindowsServiceConfiguration: Windows Service Configuration
Update-NinjaOneWebhook: Webhook
4 changes: 4 additions & 0 deletions Public/Get/Entities/Get-NinjaOneAttachment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ function Get-NinjaOneAttachment {
Attachment
.OUTPUTS
A powershell object containing the response.
.EXAMPLE
PS> Get-NinjaOneAttachment -attachmentId 'somethinggoesherebutidontknowwhatandneitherdoninja'
Retrieves the attachment with id 'somethinggoesherebutidontknowwhatandneitherdoninja'.
.LINK
https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/attachment
#>
Expand Down
20 changes: 17 additions & 3 deletions Public/Get/Management/Get-NinjaOneDeviceScriptingOptions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ function Get-NinjaOneDeviceScriptingOptions {
Gets the device scripting options for the device with id 1.
.EXAMPLE
PS> (Get-NinjaOneDeviceScriptingOptions -deviceId 1).scripts
PS> Get-NinjaOneDeviceScriptingOptions -deviceId 1 -Scripts
Gets the scripts for the device with id 1.
.EXAMPLE
PS> Get-NinjaOneDeviceScriptingOptions -deviceId 1 -Categories
Gets the categories for the device with id 1.
.OUTPUTS
A powershell object containing the response.
.LINK
Expand All @@ -31,7 +35,11 @@ function Get-NinjaOneDeviceScriptingOptions {
# Built in scripts / job names should be returned in the specified language.
[Parameter(Position = 1)]
[Alias('lang')]
[String]$LanguageTag
[String]$LanguageTag,
# Return the categories list only.
[Switch]$Categories,
# Return the scripts list only.
[Switch]$Scripts
)
$CommandName = $MyInvocation.InvocationName
$Parameters = (Get-Command -Name $CommandName).Parameters
Expand All @@ -51,7 +59,13 @@ function Get-NinjaOneDeviceScriptingOptions {
}
$DeviceScriptingOptionResults = New-NinjaOneGETRequest @RequestParams
if ($DeviceScriptingOptionResults) {
return $DeviceScriptingOptionResults
if ($Categories) {
return $DeviceScriptingOptionResults.Categories
} elseif ($Scripts) {
return $DeviceScriptingOptionResults.Scripts
} else {
return $DeviceScriptingOptionResults
}
} else {
throw ('No scripting options found for device {0}.' -f $Device.SystemName)
}
Expand Down
101 changes: 67 additions & 34 deletions Public/Invoke/Invoke-NinjaOneDeviceScript.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ function Invoke-NinjaOneDeviceScript {
Script or Action
.OUTPUTS
A powershell object containing the response.
.EXAMPLE
PS> Invoke-NinjaOneDeviceScript -deviceId 1 -type 'SCRIPT' -scriptId 1
Runs the script with id 1 against the device with id 1.
.EXAMPLE
PS> Invoke-NinjaOneDeviceScript -deviceId 1 -type 'ACTION' -actionUId '00000000-0000-0000-0000-000000000000'
Runs the built-in action with uid 00000000-0000-0000-0000-000000000000 against the device with id 1.
.EXAMPLE
.LINK
https://docs.homotechsual.dev/modules/ninjaone/commandlets/Invoke/scriptoraction
#>
Expand All @@ -16,49 +26,78 @@ function Invoke-NinjaOneDeviceScript {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
Param(
# The device to run a script on.
[Parameter(Mandatory = $true)]
[string[]]$deviceId,
[Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Alias('id')]
[Int]$deviceId,
# The type - script or action.
[Parameter(Mandatory = $true)]
[Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 1, ValueFromPipelineByPropertyName)]
[Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 1, ValueFromPipelineByPropertyName)]
[ValidateSet('SCRIPT', 'ACTION')]
[object]$type,
[String]$type,
# The id of the script to run. Only used if the type is script.
[Parameter()]
[int]$scriptId,
# The unique id of the action to run. Only used if the type is action.
[Parameter()]
[string]$actionId,
[Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 2, ValueFromPipelineByPropertyName)]
[Int]$scriptId,
# The unique uid of the action to run. Only used if the type is action.
[Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 2, ValueFromPipelineByPropertyName)]
[GUID]$actionUId,
# The parameters to pass to the script or action.
[Parameter()]
[string]$parameters,
[Parameter(ParameterSetName = 'SCRIPT', Position = 3, ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'ACTION', Position = 3, ValueFromPipelineByPropertyName)]
[String]$parameters,
# The credential/role identifier to use when running the script.
[Parameter()]
[string]$runAs
[Parameter(ParameterSetName = 'SCRIPT', Position = 4, ValueFromPipelineByPropertyName)]
[Parameter(ParameterSetName = 'ACTION', Position = 4, ValueFromPipelineByPropertyName)]
[String]$runAs
)
if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to [email protected].')
exit 1
}
try {
if ($type -eq 'SCRIPT') {
$prettyAction = 'script'
} else {
$prettyAction = 'action'
}
$Device = Get-NinjaOneDevice -deviceId $deviceId
if ($Device) {
$Resource = ('v2/device/{0}/script/run' -f $deviceId)
$RunRequest = @{
type = $action
}
if ($scriptId) {
$RunRequest.id = $scriptId
}
if ($actionId) {
$RunRequest.uid = $actionId
Write-Verbose ('Getting device scripting options for device {0}.' -f $Device.SystemName)
if ($type -eq 'SCRIPT') {
$ScriptOrAction = Get-NinjaOneDeviceScriptingOptions -deviceId $deviceId -Scripts | Where-Object { $_.id -eq $scriptId -AND $_.type -eq $type }
} else {
$ScriptOrAction = Get-NinjaOneDeviceScriptingOptions -deviceId $deviceId -Scripts | Where-Object { $_.uid -eq $actionUId -AND $_.type -eq $type }
}
if ($parameters) {
$RunRequest.parameters = $parameters
if ($ScriptOrAction.Count -gt 1) {
Write-Warning ('More than one {0} matched for device {1}.' -f $prettyAction, $Device.SystemName)
Write-Verbose ('Raw {0} options: {1}' -f $prettyAction, ($ScriptOrAction | Out-String))
}
if ($runAs) {
$RunRequest.runAs = $runAs
if ($ScriptOrAction) {
Write-Verbose ('Running {0} {1} on device {2}.' -f $prettyAction, $ScriptOrAction.Name, $Device.SystemName)
$Resource = ('v2/device/{0}/script/run' -f $deviceId)
$RunRequest = @{
type = $type
}
if ($scriptId) {
$RunRequest.id = $scriptId
}
if ($actionUId) {
$RunRequest.uid = $actionUId
}
if ($parameters) {
$RunRequest.parameters = $parameters
}
if ($runAs) {
$RunRequest.runAs = $runAs
}
Write-Verbose ('Raw run request: {0}' -f ($RunRequest | Out-String))
} else {
if ($scriptId) {
throw ('Script with id {0} not found for device {1}.' -f $scriptId, $Device.SystemName)
} elseif ($actionUId) {
throw ('Action with uid {0} not found for device {1}.' -f $actionUId, $Device.SystemName)
}
}
Write-Verbose ('Raw run request: {0}' -f ($RunRequest | Out-String))
} else {
throw ('Device with id {0} not found.' -f $deviceId)
}
Expand All @@ -68,15 +107,9 @@ function Invoke-NinjaOneDeviceScript {
}
$ScriptRun = New-NinjaOnePOSTRequest @RequestParams
if ($ScriptRun -eq 204) {
if ($action -eq 'SCRIPT') {
$actionResult = 'script'
} else {
$actionResult = 'action'
}
Write-Information "Requested run for $($actionResult) on device $($deviceId) successfully."
$OIP = $InformationPreference
$InformationPreference = 'Continue'
Write-Information ('Requested run for {0} on device {1} successfully.' -f $actionResult, $deviceId)
Write-Information ('Requested run for {0} {1} on device {2} successfully.' -f $prettyAction, $ScriptOrAction.Name, $Device.SystemName)
$InformationPreference = $OIP
}
} catch {
Expand Down
3 changes: 2 additions & 1 deletion Public/Set/Set-NinjaOneDeviceApproval.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ function Set-NinjaOneDeviceApproval {
Device Approval
.OUTPUTS
A powershell object containing the response.
.EXAMPLE
.LINK
#>
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
[OutputType([Object])]
Expand Down
2 changes: 2 additions & 0 deletions Public/Set/Set-NinjaOneNodeRolePolicyAssignment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ function Set-NinjaOneNodeRolePolicyAssignment {
Node Role Policy Assignment
.OUTPUTS
A powershell object containing the response.
.LINK
https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/noderolepolicyassignment
#>
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
[OutputType([Array])]
Expand Down
5 changes: 3 additions & 2 deletions Tests/NinjaOne.Core.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Core test suite for the NinjaOne module.
#>

$ModuleName = 'NinjaOne'

BeforeAll {
$ModulePath = Split-Path -Parent -Path (Split-Path -Parent -Path $PSCommandPath)
$ModuleName = 'NinjaOne'
Expand All @@ -15,8 +17,7 @@ BeforeAll {

}

# Test that the manifest is generally correct. Not a functional test.
Describe 'Core' {
Describe ('{0} - Core Tests' -f $ModuleName) -Tags 'Module' {
It 'Manifest is valid' {
{
Test-ModuleManifest -Path $ManifestPath -ErrorAction Stop -WarningAction SilentlyContinue
Expand Down
75 changes: 75 additions & 0 deletions Tests/NinjaOne.Help.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<#
.SYNOPSIS
Help test suite for the NinjaOne module.
#>
$ModuleName = 'NinjaOne'
$ModulePath = Split-Path -Parent -Path (Split-Path -Parent -Path $PSCommandPath)
$ManifestPath = "$($ModulePath)\$($ModuleName).psd1"
BeforeAll {
$ModulePath = Split-Path -Parent -Path (Split-Path -Parent -Path $PSCommandPath)
$ModuleName = 'NinjaOne'
$ManifestPath = "$($ModulePath)\$($ModuleName).psd1"
if (Get-Module -Name $ModuleName) {
Remove-Module $ModuleName -Force
}
Import-Module $ManifestPath -Verbose:$False
}
Describe ('{0} - Help Content' -f $ModuleName) -Tags 'Module' {
Import-Module $ManifestPath
$CommonParameters = @([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
# Get a list of the exported functions.
$Module = Get-Module -Name $ModuleName
$FunctionList = $Module.ExportedFunctions.Keys
# Iterate over the list of exported functions.
foreach ($Function in $FunctionList) {
Context ('{0} - Help Content' -f $Function) {
$Help = Get-Help -Name $Function -Full | Select-Object -Property *
$RawParameters = Get-Help -Name $Function -Parameter * -ErrorAction Ignore
$FilteredParameters = $RawParameters | Where-Object {
$_.Name -and $_.Name -notin $CommonParameters
}
$Parameters = ForEach ($FilteredParameter in $FilteredParameters) {
@{
Name = $FilteredParameter.Name
Description = $FilteredParameter.Description.Text
}
}
$AST = @{
AST = Get-Content -Path ('function:/{0}' -f $Function) -ErrorAction Ignore | Select-Object -ExpandProperty AST
Parameters = $Parameters
}
$Examples = $Help.Examples.Example | ForEach-Object { @{ Example = $_ } }
# Help content tests.
## Help content exists.
It ('{0} has help content' -f $Function) -TestCases $Help {
$_ | Should -Not -BeNullOrEmpty
}
## Synopsis exists.
It ('{0} contains a synopsis' -f $Function) -TestCases $Help {
$_.Synopsis | Should -Not -BeNullOrEmpty
}
## Description exists.
It ('{0} contains a description' -f $Function) -TestCases $Help {
$_.Description | Should -Not -BeNullOrEmpty
}
## Functionality exists.
It ('{0} contains a functionality' -f $Function) -TestCases $Help {
$_.Functionality | Should -Not -BeNullOrEmpty -Because 'The functionality string is used in the documentation process to provide shorter page titles and URLs.'
}
## Example exists.
It ('{0} has at least one usage example' -f $Function) -TestCases $Help {
$_.Examples.Example.Code.Count | Should -BeGreaterOrEqual 1
}
## Examples have a title.
### This test is not currently meaningful because it is not possible to set an example title using Comment Based Help at this time. However examples do get a default `Example n` title where n is the sequential number of the example. Ref: https://github.com/PowerShell/PowerShell/issues/20712.
It ('{0} has a title for each example' -f $Function) -TestCases $Examples {
$Example.Title | Should -Not -BeNullOrEmpty
}
## Examples have a description.
It ('{0} has a description for each example' -f $Function) -TestCases $Examples -Skip:(-not $Examples) {
$Example.Remarks | Should -Not -BeNullOrEmpty -Because ('example {0} should have a description' -f $Example.Title)
}
# AST tests.
}
}
}

0 comments on commit 3f2e115

Please sign in to comment.