PSMouseJiggler.psm1

#
# PSMouseJiggler Module
# A PowerShell module to simulate mouse movements and prevent system idle
#

# Check for required assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Global variable to track jiggling state
$script:JigglingJob = $null
$script:JigglingActive = $false

#region Core Mouse Jiggling Functions

<#
.SYNOPSIS
    Starts the PSMouseJiggler to simulate mouse movements.
 
.DESCRIPTION
    Starts mouse jiggling with specified interval and movement pattern to prevent the system from going idle.
 
.PARAMETER Interval
    Time in milliseconds between mouse movements. Default is 1000ms.
 
.PARAMETER MovementPattern
    The pattern for mouse movement. Valid values: 'Random', 'Horizontal', 'Vertical', 'Circular'. Default is 'Random'.
 
.PARAMETER Duration
    Duration in seconds to run the jiggler. If not specified, runs indefinitely until stopped.
 
.EXAMPLE
    Start-PSMouseJiggler
    Starts mouse jiggling with default settings.
 
.EXAMPLE
    Start-PSMouseJiggler -Interval 2000 -MovementPattern 'Circular' -Duration 300
    Starts mouse jiggling every 2 seconds using circular pattern for 5 minutes.
#>

function Start-PSMouseJiggler {
    [CmdletBinding()]
    param (
        [Parameter()]
        [int]$Interval = 1000,

        [Parameter()]
        [ValidateSet('Random', 'Horizontal', 'Vertical', 'Circular')]
        [string]$MovementPattern = 'Random',

        [Parameter()]
        [int]$Duration = 0
    )

    if ($script:JigglingActive) {
        Write-Warning "PSMouseJiggler is already running. Use Stop-PSMouseJiggler to stop it first."
        return
    }

    Write-Host "Starting PSMouseJiggler with $MovementPattern pattern, interval: $Interval ms" -ForegroundColor Green

    $script:JigglingActive = $true
    $startTime = Get-Date

    $script:JigglingJob = Start-Job -ScriptBlock {
        param($Interval, $MovementPattern, $Duration, $StartTime)

        Add-Type -AssemblyName System.Windows.Forms
        Add-Type -AssemblyName System.Drawing

        $endTime = if ($Duration -gt 0) { $StartTime.AddSeconds($Duration) } else { [DateTime]::MaxValue }

        while ((Get-Date) -lt $endTime) {
            # Get current mouse position
            $currentPos = [System.Windows.Forms.Cursor]::Position

            # Calculate new position based on pattern
            switch ($MovementPattern) {
                'Random' {
                    $xOffset = Get-Random -Minimum -10 -Maximum 11
                    $yOffset = Get-Random -Minimum -10 -Maximum 11
                    $newPos = [System.Drawing.Point]::new($currentPos.X + $xOffset, $currentPos.Y + $yOffset)
                }
                'Horizontal' {
                    $xOffset = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { -5 } else { 5 }
                    $newPos = [System.Drawing.Point]::new($currentPos.X + $xOffset, $currentPos.Y)
                }
                'Vertical' {
                    $yOffset = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { -5 } else { 5 }
                    $newPos = [System.Drawing.Point]::new($currentPos.X, $currentPos.Y + $yOffset)
                }
                'Circular' {
                    $angle = (Get-Date).Millisecond / 1000.0 * 2 * [Math]::PI
                    $radius = 10
                    $xOffset = [Math]::Cos($angle) * $radius
                    $yOffset = [Math]::Sin($angle) * $radius
                    $newPos = [System.Drawing.Point]::new($currentPos.X + $xOffset, $currentPos.Y + $yOffset)
                }
                default {
                    $newPos = $currentPos
                }
            }

            # Move mouse to new position
            [System.Windows.Forms.Cursor]::Position = $newPos

            # Wait for specified interval
            Start-Sleep -Milliseconds $Interval
        }
    } -ArgumentList $Interval, $MovementPattern, $Duration, $startTime

    if ($Duration -gt 0) {
        Write-Host "PSMouseJiggler will run for $Duration seconds" -ForegroundColor Yellow
    } else {
        Write-Host "PSMouseJiggler is running indefinitely. Use Stop-PSMouseJiggler to stop." -ForegroundColor Yellow
    }
}

<#
.SYNOPSIS
    Stops the PSMouseJiggler.
 
.DESCRIPTION
    Stops any running mouse jiggling job.
 
.EXAMPLE
    Stop-PSMouseJiggler
    Stops the currently running mouse jiggler.
#>

function Stop-PSMouseJiggler {
    [CmdletBinding()]
    param()

    if (-not $script:JigglingActive) {
        Write-Warning "PSMouseJiggler is not currently running."
        return
    }

    if ($script:JigglingJob) {
        Stop-Job -Job $script:JigglingJob -ErrorAction SilentlyContinue
        Remove-Job -Job $script:JigglingJob -ErrorAction SilentlyContinue
        $script:JigglingJob = $null
    }

    $script:JigglingActive = $false
    Write-Host "PSMouseJiggler stopped." -ForegroundColor Green
}

<#
.SYNOPSIS
    Calculates a new mouse position based on current position and pattern.
 
.DESCRIPTION
    Internal function to determine new mouse coordinates based on movement pattern.
 
.PARAMETER CurrentPosition
    The current mouse position as a System.Drawing.Point.
 
.PARAMETER Pattern
    The movement pattern to use.
 
.EXAMPLE
    $newPos = Get-NewMousePosition -CurrentPosition $currentPos -Pattern 'Random'
#>

function Get-NewMousePosition {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [System.Drawing.Point]$CurrentPosition,

        [Parameter(Mandatory)]
        [string]$Pattern
    )

    switch ($Pattern) {
        'Random' {
            $xOffset = Get-Random -Minimum -10 -Maximum 11
            $yOffset = Get-Random -Minimum -10 -Maximum 11
            return [System.Drawing.Point]::new($CurrentPosition.X + $xOffset, $CurrentPosition.Y + $yOffset)
        }
        'Horizontal' {
            $xOffset = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { -5 } else { 5 }
            return [System.Drawing.Point]::new($CurrentPosition.X + $xOffset, $CurrentPosition.Y)
        }
        'Vertical' {
            $yOffset = if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) { -5 } else { 5 }
            return [System.Drawing.Point]::new($CurrentPosition.X, $CurrentPosition.Y + $yOffset)
        }
        'Circular' {
            $angle = (Get-Date).Millisecond / 1000.0 * 2 * [Math]::PI
            $radius = 10
            $xOffset = [Math]::Cos($angle) * $radius
            $yOffset = [Math]::Sin($angle) * $radius
            return [System.Drawing.Point]::new($CurrentPosition.X + $xOffset, $CurrentPosition.Y + $yOffset)
        }
        default {
            return $CurrentPosition
        }
    }
}

#endregion

#region GUI Functions

<#
.SYNOPSIS
    Shows the PSMouseJiggler GUI interface.
 
.DESCRIPTION
    Displays a graphical user interface for controlling the mouse jiggler.
 
.EXAMPLE
    Show-PSMouseJigglerGUI
    Opens the GUI interface.
#>

function Show-PSMouseJigglerGUI {
    [CmdletBinding()]
    param()

    # Create the main form
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "PSMouseJiggler"
    $form.Size = New-Object System.Drawing.Size(400, 300)
    $form.StartPosition = "CenterScreen"
    $form.FormBorderStyle = "FixedDialog"
    $form.MaximizeBox = $false

    # Status label
    $statusLabel = New-Object System.Windows.Forms.Label
    $statusLabel.Text = "Status: Stopped"
    $statusLabel.Location = New-Object System.Drawing.Point(20, 20)
    $statusLabel.Size = New-Object System.Drawing.Size(200, 20)
    $form.Controls.Add($statusLabel)

    # Interval input
    $intervalLabel = New-Object System.Windows.Forms.Label
    $intervalLabel.Text = "Interval (ms):"
    $intervalLabel.Location = New-Object System.Drawing.Point(20, 60)
    $intervalLabel.Size = New-Object System.Drawing.Size(80, 20)
    $form.Controls.Add($intervalLabel)

    $intervalTextBox = New-Object System.Windows.Forms.TextBox
    $intervalTextBox.Text = "1000"
    $intervalTextBox.Location = New-Object System.Drawing.Point(110, 60)
    $intervalTextBox.Size = New-Object System.Drawing.Size(100, 20)
    $form.Controls.Add($intervalTextBox)

    # Pattern selection
    $patternLabel = New-Object System.Windows.Forms.Label
    $patternLabel.Text = "Movement Pattern:"
    $patternLabel.Location = New-Object System.Drawing.Point(20, 100)
    $patternLabel.Size = New-Object System.Drawing.Size(120, 20)
    $form.Controls.Add($patternLabel)

    $patternComboBox = New-Object System.Windows.Forms.ComboBox
    $patternComboBox.Location = New-Object System.Drawing.Point(150, 100)
    $patternComboBox.Size = New-Object System.Drawing.Size(120, 20)
    $patternComboBox.DropDownStyle = "DropDownList"
    $patternComboBox.Items.AddRange(@("Random", "Horizontal", "Vertical", "Circular"))
    $patternComboBox.SelectedIndex = 0
    $form.Controls.Add($patternComboBox)

    # Duration input
    $durationLabel = New-Object System.Windows.Forms.Label
    $durationLabel.Text = "Duration (sec, 0=infinite):"
    $durationLabel.Location = New-Object System.Drawing.Point(20, 140)
    $durationLabel.Size = New-Object System.Drawing.Size(140, 20)
    $form.Controls.Add($durationLabel)

    $durationTextBox = New-Object System.Windows.Forms.TextBox
    $durationTextBox.Text = "0"
    $durationTextBox.Location = New-Object System.Drawing.Point(170, 140)
    $durationTextBox.Size = New-Object System.Drawing.Size(100, 20)
    $form.Controls.Add($durationTextBox)

    # Start button
    $startButton = New-Object System.Windows.Forms.Button
    $startButton.Text = "Start Jiggling"
    $startButton.Location = New-Object System.Drawing.Point(50, 190)
    $startButton.Size = New-Object System.Drawing.Size(100, 30)
    $startButton.Add_Click({
        try {
            $interval = [int]$intervalTextBox.Text
            $pattern = $patternComboBox.SelectedItem.ToString()
            $duration = [int]$durationTextBox.Text

            Start-PSMouseJiggler -Interval $interval -MovementPattern $pattern -Duration $duration
            $statusLabel.Text = "Status: Running ($pattern)"
            $startButton.Enabled = $false
            $stopButton.Enabled = $true
        }
        catch {
            [System.Windows.Forms.MessageBox]::Show("Error: $($_.Exception.Message)", "Error", "OK", "Error")
        }
    })
    $form.Controls.Add($startButton)

    # Stop button
    $stopButton = New-Object System.Windows.Forms.Button
    $stopButton.Text = "Stop Jiggling"
    $stopButton.Location = New-Object System.Drawing.Point(200, 190)
    $stopButton.Size = New-Object System.Drawing.Size(100, 30)
    $stopButton.Enabled = $false
    $stopButton.Add_Click({
        Stop-PSMouseJiggler
        $statusLabel.Text = "Status: Stopped"
        $startButton.Enabled = $true
        $stopButton.Enabled = $false
    })
    $form.Controls.Add($stopButton)

    # Timer to update status
    $timer = New-Object System.Windows.Forms.Timer
    $timer.Interval = 1000
    $timer.Add_Tick({
        if (-not $script:JigglingActive -and $stopButton.Enabled) {
            $statusLabel.Text = "Status: Stopped"
            $startButton.Enabled = $true
            $stopButton.Enabled = $false
        }
    })
    $timer.Start()

    # Show the form
    $form.Add_Shown({$form.Activate()})
    $form.Add_FormClosed({$timer.Stop()})
    [void]$form.ShowDialog()
}

#endregion

#region Configuration Functions

<#
.SYNOPSIS
    Gets configuration settings from the config file.
 
.DESCRIPTION
    Loads configuration from the default.json file or creates default settings.
 
.PARAMETER ConfigFilePath
    Path to the configuration file. If not specified, uses the default location.
 
.EXAMPLE
    $config = Get-Configuration
    Gets the current configuration.
#>

function Get-Configuration {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string]$ConfigFilePath
    )

    if (-not $ConfigFilePath) {
        $moduleRoot = Split-Path -Parent $PSScriptRoot
        $ConfigFilePath = Join-Path $moduleRoot "config\default.json"
    }

    if (Test-Path $ConfigFilePath) {
        try {
            $jsonContent = Get-Content -Path $ConfigFilePath -Raw | ConvertFrom-Json
            return $jsonContent
        }
        catch {
            Write-Warning "Error reading configuration file: $($_.Exception.Message)"
            return Get-DefaultConfiguration
        }
    } else {
        Write-Verbose "Configuration file not found, using defaults"
        return Get-DefaultConfiguration
    }
}

<#
.SYNOPSIS
    Saves configuration settings to the config file.
 
.DESCRIPTION
    Saves the provided configuration object to the JSON config file.
 
.PARAMETER Configuration
    The configuration object to save.
 
.PARAMETER ConfigFilePath
    Path to save the configuration file.
 
.EXAMPLE
    Save-Configuration -Configuration $config
    Saves the configuration to the default location.
#>

function Save-Configuration {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [PSCustomObject]$Configuration,

        [Parameter()]
        [string]$ConfigFilePath
    )

    if (-not $ConfigFilePath) {
        $moduleRoot = Split-Path -Parent $PSScriptRoot
        $ConfigFilePath = Join-Path $moduleRoot "config\default.json"
    }

    try {
        $configDir = Split-Path -Parent $ConfigFilePath
        if (-not (Test-Path $configDir)) {
            New-Item -ItemType Directory -Path $configDir -Force | Out-Null
        }

        $jsonContent = $Configuration | ConvertTo-Json -Depth 10
        Set-Content -Path $ConfigFilePath -Value $jsonContent -Force
        Write-Verbose "Configuration saved to $ConfigFilePath"
    }
    catch {
        Write-Error "Error saving configuration: $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Updates a specific configuration setting.
 
.DESCRIPTION
    Updates a single configuration key with a new value.
 
.PARAMETER Key
    The configuration key to update.
 
.PARAMETER Value
    The new value for the key.
 
.PARAMETER ConfigFilePath
    Path to the configuration file.
 
.EXAMPLE
    Update-Configuration -Key "MovementSpeed" -Value 150
    Updates the MovementSpeed setting to 150.
#>

function Update-Configuration {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$Key,

        [Parameter(Mandatory)]
        [object]$Value,

        [Parameter()]
        [string]$ConfigFilePath
    )

    $config = Get-Configuration -ConfigFilePath $ConfigFilePath
    $config | Add-Member -MemberType NoteProperty -Name $Key -Value $Value -Force
    Save-Configuration -Configuration $config -ConfigFilePath $ConfigFilePath
}

<#
.SYNOPSIS
    Resets configuration to default values.
 
.DESCRIPTION
    Creates a new configuration file with default settings.
 
.PARAMETER ConfigFilePath
    Path to the configuration file.
 
.EXAMPLE
    Reset-Configuration
    Resets configuration to defaults.
#>

function Reset-Configuration {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string]$ConfigFilePath
    )

    $defaultConfig = Get-DefaultConfiguration
    Save-Configuration -Configuration $defaultConfig -ConfigFilePath $ConfigFilePath
    Write-Host "Configuration reset to defaults" -ForegroundColor Green
}

function Get-DefaultConfiguration {
    return [PSCustomObject]@{
        MovementSpeed = 1000
        MovementPattern = "Random"
        AutoJiggle = $false
        Duration = 0
        GUISettings = @{
            WindowPosition = @{ X = 0; Y = 0 }
            RememberSettings = $true
        }
    }
}

#endregion

#region Movement Pattern Functions

<#
.SYNOPSIS
    Gets a random movement pattern function.
 
.DESCRIPTION
    Returns a scriptblock that represents a random movement pattern.
 
.EXAMPLE
    $pattern = Get-RandomMovementPattern
    & $pattern
#>

function Get-RandomMovementPattern {
    [CmdletBinding()]
    param()

    $patterns = @(
        { Move-Mouse -X 10 -Y 0; Start-Sleep -Milliseconds 100 },
        { Move-Mouse -X -10 -Y 0; Start-Sleep -Milliseconds 100 },
        { Move-Mouse -X 0 -Y 10; Start-Sleep -Milliseconds 100 },
        { Move-Mouse -X 0 -Y -10; Start-Sleep -Milliseconds 100 },
        { Move-Mouse -X 5 -Y 5; Start-Sleep -Milliseconds 100 },
        { Move-Mouse -X -5 -Y -5; Start-Sleep -Milliseconds 100 }
    )
    return Get-Random -InputObject $patterns
}

<#
.SYNOPSIS
    Moves the mouse cursor by relative coordinates.
 
.DESCRIPTION
    Moves the mouse cursor by the specified X and Y offsets.
 
.PARAMETER X
    Horizontal offset in pixels.
 
.PARAMETER Y
    Vertical offset in pixels.
 
.EXAMPLE
    Move-Mouse -X 10 -Y -5
    Moves the mouse 10 pixels right and 5 pixels up.
#>

function Move-Mouse {
    [CmdletBinding()]
    param (
        [Parameter()]
        [int]$X = 0,

        [Parameter()]
        [int]$Y = 0
    )

    $currentPos = [System.Windows.Forms.Cursor]::Position
    $newPos = [System.Drawing.Point]::new($currentPos.X + $X, $currentPos.Y + $Y)
    [System.Windows.Forms.Cursor]::Position = $newPos
}

<#
.SYNOPSIS
    Starts a movement pattern for a specified duration.
 
.DESCRIPTION
    Executes random movement patterns for the specified duration.
 
.PARAMETER DurationInSeconds
    Duration to run movement patterns in seconds.
 
.EXAMPLE
    Start-MovementPattern -DurationInSeconds 60
    Runs movement patterns for 60 seconds.
#>

function Start-MovementPattern {
    [CmdletBinding()]
    param (
        [Parameter()]
        [int]$DurationInSeconds = 60
    )

    $endTime = (Get-Date).AddSeconds($DurationInSeconds)
    Write-Host "Starting movement pattern for $DurationInSeconds seconds" -ForegroundColor Green

    while ((Get-Date) -lt $endTime) {
        $movementPattern = Get-RandomMovementPattern
        & $movementPattern
    }

    Write-Host "Movement pattern completed" -ForegroundColor Green
}

<#
.SYNOPSIS
    Stops the movement pattern.
 
.DESCRIPTION
    Placeholder function for stopping movement patterns.
 
.EXAMPLE
    Stop-MovementPattern
#>

function Stop-MovementPattern {
    [CmdletBinding()]
    param()

    Write-Host "Movement pattern stopped." -ForegroundColor Yellow
}

#endregion

#region Scheduled Task Functions

<#
.SYNOPSIS
    Gets scheduled tasks related to PSMouseJiggler.
 
.DESCRIPTION
    Retrieves scheduled tasks that match the specified task name pattern.
 
.PARAMETER TaskName
    Name or pattern to search for in task names.
 
.EXAMPLE
    Get-ScheduledTasks -TaskName "PSMouseJiggler"
    Gets all tasks with "PSMouseJiggler" in the name.
#>

function Get-ScheduledTasks {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string]$TaskName = "PSMouseJiggler"
    )

    try {
        $tasks = Get-ScheduledTask | Where-Object { $_.TaskName -like "*$TaskName*" }
        return $tasks
    }
    catch {
        Write-Error "Error retrieving scheduled tasks: $($_.Exception.Message)"
        return @()
    }
}

<#
.SYNOPSIS
    Creates a new scheduled task for PSMouseJiggler.
 
.DESCRIPTION
    Creates a scheduled task to run PSMouseJiggler at specified times.
 
.PARAMETER TaskName
    Name for the scheduled task.
 
.PARAMETER Action
    Command or script to execute.
 
.PARAMETER StartTime
    When to start the task.
 
.PARAMETER RepeatIntervalMinutes
    How often to repeat the task in minutes.
 
.EXAMPLE
    New-ScheduledTask -TaskName "MyJiggler" -Action "powershell.exe -Command 'Start-PSMouseJiggler'" -StartTime (Get-Date).AddMinutes(5)
    Creates a task to start jiggling in 5 minutes.
#>

function New-ScheduledTask {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$TaskName,

        [Parameter(Mandatory)]
        [string]$Action,

        [Parameter(Mandatory)]
        [datetime]$StartTime,

        [Parameter()]
        [int]$RepeatIntervalMinutes = 60
    )

    try {
        $action = New-ScheduledTaskAction -Execute $Action
        $trigger = New-ScheduledTaskTrigger -At $StartTime -Daily
        $trigger.RepeatInterval = (New-TimeSpan -Minutes $RepeatIntervalMinutes)

        Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $TaskName -Description "PSMouseJiggler Task"
        Write-Host "Scheduled task '$TaskName' created successfully" -ForegroundColor Green
    }
    catch {
        Write-Error "Error creating scheduled task: $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Removes a scheduled task.
 
.DESCRIPTION
    Removes the specified scheduled task.
 
.PARAMETER TaskName
    Name of the task to remove.
 
.EXAMPLE
    Remove-ScheduledTask -TaskName "MyJiggler"
    Removes the MyJiggler scheduled task.
#>

function Remove-ScheduledTask {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$TaskName
    )

    try {
        Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
        Write-Host "Scheduled task '$TaskName' removed successfully" -ForegroundColor Green
    }
    catch {
        Write-Error "Error removing scheduled task: $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Starts a scheduled task.
 
.DESCRIPTION
    Manually starts the specified scheduled task.
 
.PARAMETER TaskName
    Name of the task to start.
 
.EXAMPLE
    Start-ScheduledTask -TaskName "MyJiggler"
    Starts the MyJiggler scheduled task.
#>

function Start-ScheduledTask {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$TaskName
    )

    try {
        Start-ScheduledTask -TaskName $TaskName
        Write-Host "Scheduled task '$TaskName' started successfully" -ForegroundColor Green
    }
    catch {
        Write-Error "Error starting scheduled task: $($_.Exception.Message)"
    }
}

<#
.SYNOPSIS
    Stops a scheduled task.
 
.DESCRIPTION
    Stops the specified running scheduled task.
 
.PARAMETER TaskName
    Name of the task to stop.
 
.EXAMPLE
    Stop-ScheduledTask -TaskName "MyJiggler"
    Stops the MyJiggler scheduled task.
#>

function Stop-ScheduledTask {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$TaskName
    )

    try {
        Stop-ScheduledTask -TaskName $TaskName
        Write-Host "Scheduled task '$TaskName' stopped successfully" -ForegroundColor Green
    }
    catch {
        Write-Error "Error stopping scheduled task: $($_.Exception.Message)"
    }
}

#endregion

# Module cleanup when module is removed
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    if ($script:JigglingActive) {
        Stop-PSMouseJiggler
    }
}

# Export module members (this is also defined in the manifest for best practice)
Export-ModuleMember -Function @(
    'Start-PSMouseJiggler',
    'Stop-PSMouseJiggler',
    'Get-NewMousePosition',
    'Show-PSMouseJigglerGUI',
    'Get-Configuration',
    'Save-Configuration',
    'Update-Configuration',
    'Reset-Configuration',
    'Get-RandomMovementPattern',
    'Move-Mouse',
    'Start-MovementPattern',
    'Stop-MovementPattern',
    'Get-ScheduledTasks',
    'New-ScheduledTask',
    'Remove-ScheduledTask',
    'Start-ScheduledTask',
    'Stop-ScheduledTask'
)