├── .gitignore ├── CWCPoSh.psm1 ├── CWCPoSh ├── End-CWCSession.md ├── Get-CWCLastContact.md ├── Get-CWCSessions.md ├── Invoke-CWCCommand.md ├── Invoke-CWCWake.md ├── Remove-CWCSession.md └── Update-CWCSessionName.md ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ControlEventType\.txt 3 | 4 | test\.ps1 5 | -------------------------------------------------------------------------------- /CWCPoSh.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | A PowerShell wrapper for the ConnectWise Control API 4 | 5 | .DESCRIPTION 6 | This module will allow you to interact with the Control API to issue commands and retrieve data. 7 | 8 | .NOTES 9 | Version: 1.0 10 | Author: Chris Taylor 11 | Creation Date: 1/20/2016 12 | Purpose/Change: Initial script development 13 | 14 | Update Date: 1/11/2019 15 | Purpose/Change: Move to [PSCredential] authentication 16 | 17 | .LINK 18 | labtechconsulting.com 19 | #> 20 | 21 | #requires -version 3 22 | 23 | if([Net.SecurityProtocolType]::Tls) { 24 | [Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls 25 | } 26 | 27 | #region-[Functions]------------------------------------------------------------ 28 | 29 | function Get-CWCLastContact { 30 | <# 31 | .SYNOPSIS 32 | Returns the date the machine last connected to the control server. 33 | 34 | .DESCRIPTION 35 | Returns the date the machine last connected to the control server. 36 | 37 | .PARAMETER Server 38 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 39 | 40 | .PARAMETER GUID 41 | The GUID/SessionID for the machine you wish to connect to. 42 | You can retrieve session info with the 'Get-CWCSessions' commandlet 43 | 44 | On Windows clients, the launch parameters are located in the registry at: 45 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ScreenConnect Client (xxxxxxxxxxxxxxxx)\ImagePath 46 | On Linux and Mac clients, it's found in the ClientLaunchParameters.txt file in the client installation folder: 47 | /opt/screenconnect-xxxxxxxxxxxxxxxx/ClientLaunchParameters.txt 48 | 49 | .PARAMETER Credentials 50 | [PSCredential] object used to authenticate against Control. 51 | 52 | .PARAMETER User 53 | User to authenticate against the Control server. 54 | 55 | .PARAMETER Password 56 | Password to authenticate against the Control server. 57 | 58 | .PARAMETER Quiet 59 | Will output a boolean result, $True for Connected or $False for Offline. 60 | 61 | .PARAMETER Seconds 62 | Used with the Quiet switch. The number of seconds a machine needs to be offline before returning $False. 63 | 64 | .PARAMETER Group 65 | Name of session group to use. 66 | 67 | .OUTPUTS 68 | [datetime] -or [boolean] 69 | 70 | .NOTES 71 | Version: 1.1 72 | Author: Chris Taylor 73 | Creation Date: 1/20/2016 74 | Purpose/Change: Initial script development 75 | 76 | Update Date: 8/24/2018 77 | Purpose/Change: Fix Timespan Seconds duration 78 | 79 | .EXAMPLE 80 | Get-CWCLastContact -Server $Server -GUID $GUID -User $User -Password $Password 81 | Will return the last contact of the machine with that GUID. 82 | #> 83 | [CmdletBinding()] 84 | param( 85 | [Parameter(Mandatory=$True)] 86 | [string]$Server, 87 | [Parameter(Mandatory=$True)] 88 | [guid]$GUID, 89 | [Parameter(Mandatory=$True, ParameterSetName='password')] 90 | [string]$User, 91 | [Parameter(Mandatory=$True, ParameterSetName='password')] 92 | [string]$Password, 93 | [switch]$Quiet, 94 | [int]$Seconds, 95 | [string]$Group = "All Machines", 96 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 97 | [PSCredential]$Credentials 98 | ) 99 | 100 | # Time conversion 101 | $origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0 102 | $epoch = $((New-TimeSpan -Start $(Get-Date -Date "01/01/1970") -End $(Get-Date)).TotalSeconds) 103 | 104 | if($Password) { 105 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 106 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 107 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 108 | } 109 | 110 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 111 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 112 | 113 | $Body = ConvertTo-Json @(@($Group),$GUID) -Compress 114 | Write-Verbose $Body 115 | 116 | $URl = "$Server/Services/PageService.ashx/GetSessionDetails" 117 | try { 118 | $SessionDetails = Invoke-RestMethod -Uri $url -Method Post -ContentType "application/json" -Body $Body -Headers $Headers 119 | } 120 | catch { 121 | Write-Error "$($_.Exception.Message)" 122 | return 123 | } 124 | 125 | if ($SessionDetails -eq 'null' -or !$SessionDetails) { 126 | Write-Error "Machine not found." 127 | return $null 128 | } 129 | 130 | # Filter to only guest session events 131 | $GuestSessionEvents = ($SessionDetails.Connections | Where-Object {$_.ProcessType -eq 2}).Events 132 | 133 | if ($GuestSessionEvents) { 134 | 135 | # Get connection events 136 | $LatestEvent = ($GuestSessionEvents | Where-Object {$_.EventType -in (10,11)} | Sort-Object time)[0] 137 | if ($LatestEvent.EventType -eq 10) { 138 | # Currently connected 139 | if ($Quiet) { 140 | return $True 141 | } else { 142 | return Get-Date 143 | } 144 | 145 | } 146 | else { 147 | # Time conversion hell :( 148 | $TimeDiff = $epoch - ($LatestEvent.Time /1000) 149 | $OfflineTime = $origin.AddSeconds($TimeDiff) 150 | $Difference = New-TimeSpan -Start $OfflineTime -End $(Get-Date) 151 | if ($Quiet -and $Difference.TotalSeconds -lt $Seconds) { 152 | return $True 153 | } elseif ($Quiet) { 154 | return $False 155 | } else { 156 | return $OfflineTime 157 | } 158 | } 159 | } 160 | else { 161 | Write-Error "Unable to determine last contact." 162 | return 163 | } 164 | } 165 | 166 | function Invoke-CWCCommand { 167 | <# 168 | .SYNOPSIS 169 | Will issue a command against a given machine and return the results. 170 | 171 | .DESCRIPTION 172 | Will issue a command against a given machine and return the results. 173 | 174 | .PARAMETER Server 175 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 176 | 177 | .PARAMETER GUID 178 | The GUID identifier for the machine you wish to connect to. 179 | You can retrieve session info with the 'Get-CWCSessions' commandlet 180 | 181 | .PARAMETER Credentials 182 | [PSCredential] object used to authenticate against Control. 183 | 184 | .PARAMETER User 185 | User to authenticate against the Control server. 186 | 187 | .PARAMETER Password 188 | Password to authenticate against the Control server. 189 | 190 | .PARAMETER Command 191 | The command you wish to issue to the machine. 192 | 193 | .PARAMETER TimeOut 194 | The amount of time in milliseconds that a command can execute. The default is 10000 milliseconds. 195 | 196 | .PARAMETER PowerShell 197 | Issues the command in a powershell session. 198 | 199 | .PARAMETER Group 200 | Name of session group to use. 201 | 202 | .OUTPUTS 203 | The output of the Command provided. 204 | 205 | .NOTES 206 | Version: 1.0 207 | Author: Chris Taylor 208 | Creation Date: 1/20/2016 209 | Purpose/Change: Initial script development 210 | 211 | .EXAMPLE 212 | Invoke-CWCCommand -Server $Server -GUID $GUID -User $User -Password $Password -Command 'hostname' 213 | Will return the hostname of the machine. 214 | 215 | .EXAMPLE 216 | Invoke-CWCCommand -Server $Server -GUID $GUID -User $User -Password $Password -TimeOut 120000 -Command 'iwr -UseBasicParsing "https://bit.ly/ltposh" | iex; Restart-LTService' -PowerShell 217 | Will restart the Automate agent on the target machine. 218 | #> 219 | [CmdletBinding()] 220 | param ( 221 | [Parameter(Mandatory=$True)] 222 | [string]$Server, 223 | [Parameter(Mandatory=$True)] 224 | [guid]$GUID, 225 | [Parameter(Mandatory=$True, ParameterSetName='password')] 226 | [string]$User, 227 | [Parameter(Mandatory=$True, ParameterSetName='password')] 228 | [string]$Password, 229 | [string]$Command, 230 | [int]$TimeOut = 10000, 231 | [switch]$PowerShell, 232 | [string]$Group = "All Machines", 233 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 234 | [PSCredential]$Credentials 235 | ) 236 | 237 | if($Password) { 238 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 239 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 240 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 241 | } 242 | 243 | $origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0 244 | 245 | $URI = "$Server/Services/PageService.ashx/AddEventToSessions" 246 | 247 | # Format command 248 | $FormattedCommand = @() 249 | if ($Powershell) { 250 | $FormattedCommand += '#!ps' 251 | } 252 | $FormattedCommand += "#timeout=$TimeOut" 253 | $FormattedCommand += $Command 254 | $FormattedCommand = $FormattedCommand | Out-String 255 | 256 | $SessionEventType = 44 257 | $Body = (ConvertTo-Json @($Group,@($GUID),$SessionEventType,$FormattedCommand)).Replace('\r\n','\n') 258 | Write-Verbose $Body 259 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 260 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 261 | 262 | # Issue command 263 | try { 264 | $null = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 265 | } 266 | catch { 267 | Write-Error $_ 268 | return 269 | } 270 | 271 | # Get Session 272 | $URI = "$Server/Services/PageService.ashx/GetSessionDetails" 273 | $Body = ConvertTo-Json @($Group,$GUID) 274 | Write-Verbose $Body 275 | try { 276 | $SessionDetails = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 277 | } 278 | catch { 279 | Write-Error $_ 280 | return 281 | } 282 | 283 | #Get time command was executed 284 | $epoch = $((New-TimeSpan -Start $(Get-Date -Date "01/01/1970") -End $(Get-Date)).TotalSeconds) 285 | $ExecuteTime = $epoch - ((($SessionDetails.events | Where-Object {$_.EventType -eq 44})[-1]).Time /1000) 286 | $ExecuteDate = $origin.AddSeconds($ExecuteTime) 287 | 288 | # Look for results of command 289 | $Looking = $True 290 | $TimeOutDateTime = (Get-Date).AddMilliseconds($TimeOut) 291 | $Body = ConvertTo-Json @($Group,$GUID) 292 | while ($Looking) { 293 | try { 294 | $SessionDetails = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 295 | } 296 | catch { 297 | Write-Error $_ 298 | return 299 | } 300 | 301 | $ConnectionsWithData = @() 302 | Foreach ($Connection in $SessionDetails.connections) { 303 | $ConnectionsWithData += $Connection | Where-Object {$_.Events.EventType -eq 70} 304 | } 305 | 306 | $Events = ($ConnectionsWithData.events | Where-Object {$_.EventType -eq 70 -and $_.Time}) 307 | foreach ($Event in $Events) { 308 | $epoch = $((New-TimeSpan -Start $(Get-Date -Date "01/01/1970") -End $(Get-Date)).TotalSeconds) 309 | $CheckTime = $epoch - ($Event.Time /1000) 310 | $CheckDate = $origin.AddSeconds($CheckTime) 311 | if ($CheckDate -gt $ExecuteDate) { 312 | $Looking = $False 313 | $Output = $Event.Data -split '[\r\n]' | Where-Object {$_ -and $_ -ne "C:\WINDOWS\system32>$Command"} 314 | Write-Verbose $Event.Data 315 | return $Output 316 | } 317 | } 318 | 319 | Start-Sleep -Seconds 1 320 | if ($(Get-Date) -gt $TimeOutDateTime.AddSeconds(1)) { 321 | $Looking = $False 322 | Write-Warning "Command timed out." 323 | } 324 | } 325 | } 326 | 327 | function Get-CWCSessions { 328 | <# 329 | .SYNOPSIS 330 | Will return a list of sessions. 331 | 332 | .DESCRIPTION 333 | Allows you to search for access or service sessions. 334 | 335 | .PARAMETER Server 336 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 337 | 338 | .PARAMETER Credentials 339 | [PSCredential] object used to authenticate against Control. 340 | 341 | .PARAMETER User 342 | User to authenticate against the Control server. 343 | 344 | .PARAMETER Password 345 | Password to authenticate against the Control server. 346 | 347 | .PARAMETER Type 348 | The type of session Support/Access 349 | 350 | .PARAMETER Group 351 | Name of session group to use. 352 | 353 | .PARAMETER Search 354 | Limit results with search pattern. 355 | 356 | .PARAMETER Limit 357 | Limit the number of results returned. 358 | 359 | .OUTPUTS 360 | ConnectWise Control session objects 361 | 362 | .NOTES 363 | Version: 1.0 364 | Author: Chris Taylor 365 | Creation Date: 10/10/2018 366 | Purpose/Change: Initial script development 367 | 368 | .EXAMPLE 369 | Get-CWCAccessSessions -Server $Server -User $User -Password $Password -Search "server1" -Limit 10 370 | Will return the first 10 access sessions that match 'server1'. 371 | 372 | #> 373 | [CmdletBinding()] 374 | param ( 375 | [Parameter(Mandatory=$True)] 376 | [string]$Server, 377 | [Parameter(Mandatory=$True, ParameterSetName='password')] 378 | [string]$User, 379 | [Parameter(Mandatory=$True, ParameterSetName='password')] 380 | [string]$Password, 381 | [Parameter(Mandatory=$True)] 382 | [ValidateSet('Support','Access')] 383 | $Type, 384 | [string]$Group = "All Machines", 385 | [string]$Search, 386 | [int]$Limit, 387 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 388 | [PSCredential]$Credentials 389 | ) 390 | 391 | if($Password) { 392 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 393 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 394 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 395 | } 396 | 397 | $URI = "$Server/Services/PageService.ashx/GetHostSessionInfo" 398 | 399 | switch($Type){ 400 | 'Support' {$Number = 0} 401 | 'Meeting' {$Number = 1} 402 | 'Access' {$Number = 2} 403 | default {Write-Error "Unknown Type, $Type";return} 404 | } 405 | 406 | $Body = ConvertTo-Json @($Number,@($Group),$Search,$null,$Limit) 407 | Write-Verbose $Body 408 | 409 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 410 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 411 | 412 | try { 413 | $Data = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 414 | return $Data.sessions 415 | } 416 | catch { 417 | Write-Error $_ 418 | return 419 | } 420 | } 421 | 422 | function Remove-CWCSession { 423 | <# 424 | .SYNOPSIS 425 | Will end a given session. 426 | 427 | .DESCRIPTION 428 | Will end a given access or support session. 429 | 430 | .PARAMETER Server 431 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 432 | 433 | .PARAMETER Credentials 434 | [PSCredential] object used to authenticate against Control. 435 | 436 | .PARAMETER User 437 | User to authenticate against the Control server. 438 | 439 | .PARAMETER Password 440 | Password to authenticate against the Control server. 441 | 442 | .PARAMETER Type 443 | The type of session Support/Meeting/Access 444 | 445 | .PARAMETER GUID 446 | The GUID identifier for the session you wish to end. Accepts an array of GUIDs. 447 | 448 | .NOTES 449 | Version: 1.0 450 | Author: Chris Taylor 451 | Creation Date: 10/10/2018 452 | Purpose/Change: Initial script development 453 | 454 | .EXAMPLE 455 | Remove-CWCAccessSession -Server $Server -GUID $GUID -User $User -Password $Password 456 | Will remove the given access session 457 | #> 458 | [CmdletBinding()] 459 | param ( 460 | [Parameter(Mandatory=$True)] 461 | [string]$Server, 462 | [Parameter(Mandatory=$True)] 463 | [guid[]]$GUID, 464 | [Parameter(Mandatory=$True, ParameterSetName='password')] 465 | [string]$User, 466 | [Parameter(Mandatory=$True, ParameterSetName='password')] 467 | [string]$Password, 468 | [Parameter(Mandatory=$True)] 469 | [ValidateSet('Access','Meeting','Support')] 470 | $Type, 471 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 472 | [PSCredential]$Credentials 473 | ) 474 | 475 | if($Password) { 476 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 477 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 478 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 479 | } 480 | 481 | $URI = "$Server/Services/PageService.ashx/AddEventToSessions" 482 | 483 | switch($Type){ 484 | 'Support' {$Group = 'All Sessions'} 485 | 'Access' {$Group = 'All Machines'} 486 | default {Write-Error "Unknown Type, $Type";return} 487 | } 488 | 489 | $SessionEventType = 21 490 | if($GUID.count -eq 1){ 491 | $Body = ConvertTo-Json @(@($Group),@($GUID),$SessionEventType,'') 492 | } 493 | else { 494 | $Body = ConvertTo-Json @(@($Group),$GUID,$SessionEventType,'') 495 | } 496 | Write-Verbose $Body 497 | 498 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 499 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 500 | 501 | # Issue command 502 | try { 503 | $null = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 504 | } 505 | catch { 506 | Write-Error $(($_.ErrorDetails | ConvertFrom-Json).message) 507 | return 508 | } 509 | } 510 | 511 | function Update-CWCSessionName { 512 | <# 513 | .SYNOPSIS 514 | Updates the name of a session. 515 | 516 | .DESCRIPTION 517 | Updates the name of a session on the control server. 518 | 519 | .PARAMETER Server 520 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 521 | 522 | .PARAMETER GUID 523 | The GUID/SessionID for the machine you wish to connect to. 524 | You can retrieve session info with the 'Get-CWCSessions' commandlet 525 | 526 | On Windows clients, the launch parameters are located in the registry at: 527 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ScreenConnect Client (xxxxxxxxxxxxxxxx)\ImagePath 528 | On Linux and Mac clients, it's found in the ClientLaunchParameters.txt file in the client installation folder: 529 | /opt/screenconnect-xxxxxxxxxxxxxxxx/ClientLaunchParameters.txt 530 | 531 | .PARAMETER Credentials 532 | [PSCredential] object used to authenticate against Control. 533 | 534 | .PARAMETER User 535 | User to authenticate against the Control server. 536 | 537 | .PARAMETER Password 538 | Password to authenticate against the Control server. 539 | 540 | .PARAMETER NewName 541 | The new name for the session. 542 | 543 | .NOTES 544 | Version: 1.1 545 | Author: Chris Taylor 546 | Creation Date: 10/25/2018 547 | Purpose/Change: Initial script development 548 | 549 | .EXAMPLE 550 | Update-CWCSessionName -Server $Server -GUID $GUID -User $User -Password $Password -NewName 'Session1' 551 | Will rename the session to Session1 552 | #> 553 | [CmdletBinding()] 554 | param( 555 | [Parameter(Mandatory=$True)] 556 | [string]$Server, 557 | [Parameter(Mandatory=$True)] 558 | [guid]$GUID, 559 | [Parameter(Mandatory=$True, ParameterSetName='password')] 560 | [string]$User, 561 | [Parameter(Mandatory=$True, ParameterSetName='password')] 562 | [string]$Password, 563 | [Parameter(Mandatory=$True)] 564 | [string]$NewName, 565 | [string]$Group = "All Machines", 566 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 567 | [PSCredential]$Credentials 568 | ) 569 | 570 | if($Password) { 571 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 572 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 573 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 574 | } 575 | 576 | $Body = ConvertTo-Json @($Group,$GUID,$NewName) 577 | Write-Verbose $Body 578 | 579 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 580 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 581 | 582 | $URl = "$Server/Services/PageService.ashx/UpdateSessionName" 583 | try { 584 | $null = Invoke-RestMethod -Uri $url -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 585 | } 586 | catch { 587 | Write-Error $_.Exception.Message 588 | return 589 | } 590 | } 591 | 592 | function Invoke-CWCWake { 593 | <# 594 | .SYNOPSIS 595 | Will issue a wake command to a given session. 596 | 597 | .DESCRIPTION 598 | Will issue a wake command to a given access or support session. 599 | 600 | .PARAMETER Server 601 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 602 | 603 | .PARAMETER Credentials 604 | [PSCredential] object used to authenticate against Control. 605 | 606 | .PARAMETER User 607 | User to authenticate against the Control server. 608 | 609 | .PARAMETER Password 610 | Password to authenticate against the Control server. 611 | 612 | .PARAMETER Type 613 | The type of session Support/Access 614 | 615 | .PARAMETER GUID 616 | The GUID identifier for the session you wish to end. Accepts an array of GUIDs 617 | 618 | .NOTES 619 | Version: 1.0 620 | Author: Chris Taylor 621 | Creation Date: 12/7/2018 622 | Purpose/Change: Initial script development 623 | 624 | .EXAMPLE 625 | End-CWWake -Server $Server -GUID $GUID -User $User -Password $Password 626 | Will issue a wake command to a given session. 627 | #> 628 | [CmdletBinding()] 629 | param ( 630 | [Parameter(Mandatory=$True)] 631 | [string]$Server, 632 | [Parameter(Mandatory=$True)] 633 | [guid[]]$GUID, 634 | [Parameter(Mandatory=$True, ParameterSetName='password')] 635 | [string]$User, 636 | [Parameter(Mandatory=$True, ParameterSetName='password')] 637 | [string]$Password, 638 | [Parameter(Mandatory=$True)] 639 | [ValidateSet('Support','Access')] 640 | [string]$Type, 641 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 642 | [PSCredential]$Credentials 643 | ) 644 | 645 | if($Password) { 646 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 647 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 648 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 649 | } 650 | 651 | $URI = "$Server/Services/PageService.ashx/AddEventToSessions" 652 | 653 | switch($Type){ 654 | 'Support' {$Group = 'All Sessions'} 655 | 'Access' {$Group = 'All Machines'} 656 | default {Write-Error "Unknown Type, $Type";return} 657 | } 658 | 659 | $SessionEventType = 43 660 | if($GUID.count -eq 1){ 661 | $Body = ConvertTo-Json @($Group,@($GUID),$SessionEventType,'') 662 | } 663 | else { 664 | $Body = ConvertTo-Json @($Group,$GUID,$SessionEventType,'') 665 | } 666 | 667 | Write-Verbose $Body 668 | 669 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 670 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 671 | 672 | # Issue command 673 | try { 674 | $null = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 675 | } 676 | catch { 677 | Write-Error $_ 678 | return 679 | } 680 | } 681 | 682 | function Get-CWCSessionDetail { 683 | <# 684 | .SYNOPSIS 685 | Will return information about a session. 686 | 687 | .DESCRIPTION 688 | Dispays more information about a session. 689 | 690 | .PARAMETER Server 691 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 692 | 693 | .PARAMETER Credentials 694 | [PSCredential] object used to authenticate against Control. 695 | 696 | .PARAMETER User 697 | User to authenticate against the Control server. 698 | 699 | .PARAMETER Password 700 | Password to authenticate against the Control server. 701 | 702 | .PARAMETER Group 703 | Name of session group to use. 704 | 705 | .PARAMETER GUID 706 | GUID of the machine to retreive session details. 707 | 708 | .OUTPUTS 709 | ConnectWise Control session objects 710 | 711 | .NOTES 712 | Version: 1.0 713 | Author: Chris Taylor 714 | Creation Date: 1/15/2019 715 | Purpose/Change: Initial script development 716 | 717 | .EXAMPLE 718 | Get-CWCAccessSessions -Server $Server -User $User -Password $Password -Search "server1" -Limit 10 719 | Will return the first 10 access sessions that match 'server1'. 720 | 721 | #> 722 | [CmdletBinding()] 723 | param ( 724 | [Parameter(Mandatory=$True)] 725 | [string]$Server, 726 | [Parameter(Mandatory=$True, ParameterSetName='password')] 727 | [string]$User, 728 | [Parameter(Mandatory=$True, ParameterSetName='password')] 729 | [string]$Password, 730 | [string]$Group = "All Machines", 731 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 732 | [PSCredential]$Credentials, 733 | [Parameter(Mandatory=$True)] 734 | [guid]$GUID 735 | ) 736 | 737 | if($Password) { 738 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 739 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 740 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 741 | } 742 | 743 | $URI = "$Server/Services/PageService.ashx/GetSessionDetails" 744 | 745 | $Body = ConvertTo-Json @($Group,$GUID) 746 | Write-Verbose $Body 747 | 748 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 749 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 750 | 751 | try { 752 | $Data = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json; charset=utf-8" -Body $Body -Verbose 753 | return $Data 754 | } 755 | catch { 756 | Write-Error $_ 757 | return 758 | } 759 | } 760 | 761 | function Update-CWCCustomProperty { 762 | <# 763 | .SYNOPSIS 764 | Updated the custom . 765 | 766 | .DESCRIPTION 767 | Updates the name of a session on the control server. 768 | 769 | .PARAMETER Server 770 | The address to your Control server. Example 'https://control.labtechconsulting.com' or 'http://control.secure.me:8040' 771 | 772 | .PARAMETER GUID 773 | The GUID/SessionID for the machine you wish to connect to. 774 | You can retrieve session info with the 'Get-CWCSessions' commandlet 775 | 776 | On Windows clients, the launch parameters are located in the registry at: 777 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ScreenConnect Client (xxxxxxxxxxxxxxxx)\ImagePath 778 | On Linux and Mac clients, it's found in the ClientLaunchParameters.txt file in the client installation folder: 779 | /opt/screenconnect-xxxxxxxxxxxxxxxx/ClientLaunchParameters.txt 780 | 781 | .PARAMETER Credentials 782 | [PSCredential] object used to authenticate against Control. 783 | 784 | .PARAMETER User 785 | User to authenticate against the Control server. 786 | 787 | .PARAMETER Password 788 | Password to authenticate against the Control server. 789 | 790 | .PARAMETER NewName 791 | The new name for the session. 792 | 793 | .NOTES 794 | Version: 1.1 795 | Author: Chris Taylor 796 | Creation Date: 10/25/2018 797 | Purpose/Change: Initial script development 798 | 799 | .EXAMPLE 800 | Update-CWCSessionName -Server $Server -GUID $GUID -User $User -Password $Password -NewName 'Session1' 801 | Will rename the session to Session1 802 | #> 803 | [CmdletBinding()] 804 | param( 805 | [Parameter(Mandatory=$True)] 806 | [string]$Server, 807 | [Parameter(Mandatory=$True)] 808 | [guid]$GUID, 809 | [Parameter(Mandatory=$True, ParameterSetName='password')] 810 | [string]$User, 811 | [Parameter(Mandatory=$True, ParameterSetName='password')] 812 | [string]$Password, 813 | [Parameter(Mandatory=$True)] 814 | [string]$NewName, 815 | [string]$Group = "All Machines", 816 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 817 | [PSCredential]$Credentials 818 | ) 819 | 820 | if($Password) { 821 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 822 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 823 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 824 | } 825 | 826 | $Body = ConvertTo-Json @($Group,$GUID,$NewName) 827 | Write-Verbose $Body 828 | 829 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 830 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 831 | 832 | $URl = "$Server/Services/PageService.ashx/UpdateSessionName" 833 | try { 834 | $null = Invoke-RestMethod -Uri $url -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 835 | } 836 | catch { 837 | Write-Error $_ 838 | return 839 | } 840 | } 841 | 842 | function New-CWCUser { 843 | <# 844 | .SYNOPSIS 845 | Creates a user. 846 | 847 | .DESCRIPTION 848 | Creates a new local user. 849 | 850 | .PARAMETER Server 851 | The ConnectWise Control server you care connecting to 852 | 853 | .PARAMETER Credentials 854 | Credentials of the non MFA user used to perform the actions. 855 | 856 | .PARAMETER UserName 857 | Username of the new user 858 | 859 | .PARAMETER Password 860 | Password of the new user 861 | 862 | .PARAMETER OPT 863 | The MFA token 864 | 865 | .PARAMETER DisplayName 866 | The display name of the new user 867 | 868 | .PARAMETER SecurityGroups 869 | An array of security groups the user is a part of 870 | 871 | .PARAMETER ForcePassChange 872 | Force the user to change their password at next login 873 | 874 | .NOTES 875 | Version: 1.1 876 | Author: Chris Taylor 877 | Creation Date: 4/2/2020 878 | Purpose/Change: Initial script development 879 | 880 | .EXAMPLE 881 | 882 | #> 883 | [CmdletBinding()] 884 | param( 885 | [Parameter(Mandatory=$True)] 886 | [string]$Server, 887 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 888 | [PSCredential]$Credentials, 889 | [Parameter(Mandatory=$True)] 890 | [string]$UserName, 891 | [Parameter(Mandatory=$True)] 892 | [string]$Password, 893 | [string]$OTP, 894 | [string]$DisplayName, 895 | [string]$Email, 896 | [string[]]$SecurityGroups, 897 | [boolean]$ForcePassChange = $true 898 | ) 899 | 900 | $Body = ConvertTo-Json -Depth 10 @( 901 | "XmlMembershipProvider", 902 | $null, 903 | $UserName, 904 | $Password, 905 | $Password, 906 | $OTP, 907 | $DisplayName, 908 | "", 909 | $Email, 910 | $SecurityGroups, 911 | $ForcePassChange 912 | ) 913 | Write-Verbose $Body 914 | 915 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 916 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 917 | 918 | $URl = "$Server/Services/SecurityService.ashx/SaveUser" 919 | $null = Invoke-RestMethod -Uri $url -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 920 | } 921 | 922 | function New-CWCAssignment { 923 | <# 924 | .SYNOPSIS 925 | Assign a user to machines. 926 | 927 | .DESCRIPTION 928 | Uses the remote workforce extension to assign a user to machines 929 | 930 | .PARAMETER Server 931 | 932 | .PARAMETER GUID 933 | 934 | .PARAMETER Credentials 935 | 936 | .PARAMETER User 937 | 938 | .PARAMETER Password 939 | 940 | .PARAMETER NewName 941 | 942 | .NOTES 943 | Version: 1.1 944 | Author: Chris Taylor 945 | Creation Date: 10/25/2018 946 | Purpose/Change: Initial script development 947 | 948 | .EXAMPLE 949 | 950 | #> 951 | [CmdletBinding()] 952 | param( 953 | [Parameter(Mandatory=$True)] 954 | [string]$Server, 955 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 956 | [PSCredential]$Credentials, 957 | [Parameter(Mandatory=$True)] 958 | [guid[]]$GUID, 959 | [Parameter(Mandatory=$True)] 960 | [string]$Username, 961 | [string]$DisplayName 962 | ) 963 | 964 | $Body = ConvertTo-Json @( 965 | $GUID, 966 | "UserName:$($Username),UserDisplayName:$($DisplayName)" 967 | ) 968 | Write-Verbose $Body 969 | 970 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 971 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 972 | 973 | $URl = "$Server/App_Extensions/2c4f522f-b39a-413a-8807-dc52a2fce13e/Service.ashx/AddAssignmentNoteToSession" 974 | $null = Invoke-RestMethod -Uri $url -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 975 | } 976 | 977 | function createRequiredRemoteWorkforceRole { 978 | <# 979 | .SYNOPSIS 980 | Create a new security role 981 | 982 | .DESCRIPTION 983 | Create a new security role 984 | 985 | .PARAMETER Server 986 | 987 | .PARAMETER GUID 988 | 989 | .PARAMETER Credentials 990 | 991 | .PARAMETER User 992 | 993 | .PARAMETER Password 994 | 995 | .PARAMETER NewName 996 | 997 | .NOTES 998 | Version: 1.1 999 | Author: Chris Taylor 1000 | Creation Date: 10/25/2018 1001 | Purpose/Change: Initial script development 1002 | 1003 | .EXAMPLE 1004 | 1005 | #> 1006 | [CmdletBinding()] 1007 | param( 1008 | [Parameter(Mandatory=$True)] 1009 | [string]$Server, 1010 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 1011 | [PSCredential]$Credentials, 1012 | $SessionGroups = @('My Assigned Machines'), 1013 | $RoleName = 'Remote Workforce' 1014 | ) 1015 | 1016 | $Body = ConvertTo-Json -Depth 10 @( 1017 | "", 1018 | $RoleName, 1019 | @(), 1020 | @( 1021 | @{ 1022 | "AccessControlType" = 0 1023 | "Name" = "ViewSessionGroup" 1024 | "SessionGroupFilter" = 7 1025 | "SessionGroupPath" = $SessionGroups 1026 | "OwnershipFilter" = 0 1027 | }, 1028 | @{ 1029 | "AccessControlType" = 0 1030 | "Name" = "JoinSession" 1031 | "SessionGroupFilter" = 7 1032 | "SessionGroupPath" = $SessionGroups 1033 | "OwnershipFilter" = 0 1034 | }, 1035 | @{ 1036 | "AccessControlType" = 0 1037 | "Name" = "HostSessionWithoutConsent" 1038 | "SessionGroupFilter" = 7 1039 | "SessionGroupPath" = $SessionGroups 1040 | "OwnershipFilter" = 0 1041 | } 1042 | ) 1043 | ) 1044 | Write-Verbose $Body 1045 | 1046 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 1047 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 1048 | 1049 | $URl = "$Server/Services/SecurityService.ashx/SaveRole" 1050 | $null = Invoke-RestMethod -Uri $url -Method Post -Headers $Headers -ContentType "application/json" -Body $Body 1051 | } 1052 | 1053 | function New-CWCMFA { 1054 | $Possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" 1055 | $Key = "" 1056 | while ($Key.Length -lt 16) { 1057 | $Key += $Possible.ToCharArray() | Get-Random 1058 | } 1059 | 1060 | $googleUrlLabel = "otpauth://totp/screenconnect?secret=$Key" 1061 | $qrUrl = "https://chart.googleapis.com/chart?cht=qr&chs=300x300&chl=$($googleUrlLabel)&chld=H|0" 1062 | [pscustomobject]@{ 1063 | 'QR' = $qrUrl 1064 | 'OTP' = "ms:$Key" 1065 | } 1066 | } 1067 | 1068 | function Get-CWCSecurityConfigurationInfo { 1069 | <# 1070 | .SYNOPSIS 1071 | Will return security configuration information. 1072 | 1073 | .DESCRIPTION 1074 | Will return security configuration information. 1075 | 1076 | .PARAMETER Server 1077 | The address to your Control server. Example 'https://control.christaylor.codes' or 'http://control.secure.me:8040' 1078 | 1079 | .PARAMETER Credentials 1080 | PSCredential object used to authenticate against Control. 1081 | 1082 | .PARAMETER User 1083 | User to authenticate against the Control server. 1084 | 1085 | .PARAMETER Password 1086 | Password to authenticate against the Control server. 1087 | 1088 | .PARAMETER Group 1089 | Name of session group to use. 1090 | 1091 | .PARAMETER GUID 1092 | GUID of the machine to retrieve session details. 1093 | 1094 | .OUTPUTS 1095 | ConnectWise Control session objects 1096 | 1097 | .NOTES 1098 | Version: 1.0 1099 | Author: Chris Taylor 1100 | Creation Date: 1/15/2019 1101 | Purpose/Change: Initial script development 1102 | 1103 | .EXAMPLE 1104 | Get-CWCAccessSessions -Server $Server -User $User -Password $Password -Search "server1" -Limit 10 1105 | Will return the first 10 access sessions that match 'server1'. 1106 | 1107 | #> 1108 | [CmdletBinding()] 1109 | param ( 1110 | [Parameter(Mandatory=$True)] 1111 | [string]$Server, 1112 | [Parameter(Mandatory=$True, ParameterSetName='password')] 1113 | [string]$User, 1114 | [Parameter(Mandatory=$True, ParameterSetName='password')] 1115 | [string]$Password, 1116 | [string]$Group = "All Machines", 1117 | [Parameter(Mandatory=$True, ParameterSetName='cred')] 1118 | [PSCredential]$Credentials 1119 | ) 1120 | 1121 | if($Password) { 1122 | $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force 1123 | $Credentials = New-Object System.Management.Automation.PSCredential ($User, $secpasswd) 1124 | Write-Warning "Switch to -Credentials [PSCredential] authentication method." 1125 | } 1126 | 1127 | $URI = "$Server/Services/SecurityService.ashx/GetSecurityConfigurationInfo" 1128 | 1129 | $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Credentials.GetNetworkCredential().Password)")) 1130 | $Headers = @{ Authorization = "Basic $encodedCredentials" } 1131 | 1132 | $Data = Invoke-RestMethod -Uri $URI -Method Post -Headers $Headers -ContentType "application/json; charset=utf-8" 1133 | return $Data 1134 | } 1135 | 1136 | #endregion Functions 1137 | -------------------------------------------------------------------------------- /CWCPoSh/End-CWCSession.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/End-CWCSession.md -------------------------------------------------------------------------------- /CWCPoSh/Get-CWCLastContact.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Get-CWCLastContact.md -------------------------------------------------------------------------------- /CWCPoSh/Get-CWCSessions.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Get-CWCSessions.md -------------------------------------------------------------------------------- /CWCPoSh/Invoke-CWCCommand.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Invoke-CWCCommand.md -------------------------------------------------------------------------------- /CWCPoSh/Invoke-CWCWake.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Invoke-CWCWake.md -------------------------------------------------------------------------------- /CWCPoSh/Remove-CWCSession.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Remove-CWCSession.md -------------------------------------------------------------------------------- /CWCPoSh/Update-CWCSessionName.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabtechConsulting/ConnectWiseControlPowerShell/870b10ca387adbfe997fda15680c1a9b6648ca6b/CWCPoSh/Update-CWCSessionName.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 LabTech Consulting 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This module is no longer maintained 2 | 3 | Please migrate to https://github.com/christaylorcodes/ConnectWiseControlAPI 4 | --------------------------------------------------------------------------------