Code Monkey home page Code Monkey logo

psconnectwise's People

Contributors

persistent13 avatar sgtoj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

psconnectwise's Issues

Add -Name and -Descending Param for All Functions

Add -Name w/ the ability to use wildcards and -Descending parameters to each of the functions. These were partially implemented with Get-CWServiceBoard and Get-CWServiceTicket. Now going to implement to all functions and make it consistent.

Add CWExpenseEntry Class

Create function to add expense entries.

Create Add-CWExpenseEntry Advanced Function
Create Get-CWExpenseEntry Advanced Function
Create Remove-CWExpenseEntry Advanced Function
Created Pester Tests for the Above

(copy/pasted from your CWTimeEntry issue - this would be a sweet addition and likely when I get some time I'll look through your code and see if I can build it out myself - if so i'll post the scripts up here)

Return Board SubTypes

Thought the ConnectWise's Service BoardType API did return subtypes too. Just tested it myself and realize it does not. So I will be looking in to how to request subtypes.

Update-CWServiceTicket unable to Update

Hi Brian

Thank you for an excellent module.

I have found some issues in regards to some of the functions that should be easy fixes.

  1. When calling a function the parameter -Server $CWServer is not referenced and needs to be changed to -Session $CWServer to work.

I have tried a couple of the functions with success but i am having issues with the one i really need.

Update-CWServiceTicket

When i call the function:
Update-CWServiceTicket -ID 751047 -StatusID 761 -Message "Changed Status" -Session $CWServer;
The ID is confirmed and exists in CW as new and i am trying to set Status to Completed.

This is the error that i get:

Update-CWServiceTicket : Parameter set cannot be resolved using the specified named parameters.
At line:40 char:2
+  Update-CWServiceTicket -ID 751047 -StatusID 761 -Message "Changed St ...
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Update-CWServiceTicket], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Update-CWServiceTicket


According to the synopsis the the supplied parameters are the only ones that are Mandatory.
I might be doing something wrong?

Thanks.

Improve CWTimeEntry Functions

TODO:

  • Ability to retrieve more than 50 time entries.
  • Ability to retrieve info about all time entries of a ticket
    • even if it is 5k entries on a single ticket
    • probably will limit it to basic information only
  • Write test for -Detailed switch for Get-CWTimeEntry
  • Add ability to change member on TimeEntry

Documentation for cmdlets

I'm trying to use the Update-CWServiceTicket function, but without proper documentation I'm just randomly trying the switches to see what they do and what they require when paired with different ones.

Is there documentation somewhere that I can look at? I don't see anything relevant under the docs folder, only instructions for creating keys.

Add Get-CWMember

Create function to retrieve CW member information

  • Review CW's System Member module
  • Create CWAPI... service
  • Create Get-CWMember advanced function
  • Create Test for Get-CWMember
  • Test and debug the new adv-fn and Pester test(s)

Module Rewrite

These past few months, I have been thinking about the future of this project. I have come to the conclusion that I need to rewrite this PowerShell module.

  • Use CW Manage's Swagger Spec Documents to Generate Cmdlet
  • Add Support for Mac and Linux
    • Ensure Support for PS 5.0 and 6.0.
    • Investigate Rewriting the Module's Core in C# .NET Core 2.0.
      • In retrospect, writing Module Core in PS 5.0 Class was not the best for maintainability.
    • Investigate using ConnectWise Manage's official .NET SDK for Module's Core
      • Must support Linux and Mac
  • Improve the Contribution Process and Turn Around Time
    • Rewrite Pester (aka Unit) Tests to Use Stubs and Mocks
    • Develop Automated CI Pipeline
    • Choose a free CI service like Travis-CI
  • Query Functions (e.g. Get-CWServiceTicket) should return Objects
    • Instead of raw JSON from the CW Manage API.
  • Rebrand this Project to Include Manage its Name
  • Add Support for Secure Strings from Credentials

I do apologize to those, like @vedeht, who have been waiting on the continued development of this project. I have learned a lot about open develop projects since writing this one (it was my first OSS project). Now I want to put it all together.

Update-CWCompanyContact

It would be good to have the ability to update a company contact info to include firstname, last name, email, phone, etc

ConnectWise time normalization

In trying to do a Create-CWConfig function, I ran into this terrible annoyance with the way that CW needs to receive [datetime] via the API. I wrote this little function that helps. Figured it would help you and your users so they didn't bang their head against the same problems I did.

function ConvertTo-CWTime
{
Param
(
[Parameter(Mandatory = $True,Position = 0)]
[datetime]$dateTime
)
$MyTZone = Get-TimeZone
$datetime = "{0:yyyy-MM-ddThh:mm:ssZ}" -f [System.TimeZoneInfo]::ConvertTimeToUtc($dateTime, $MyTZone)
return $datetime
}

Add Logic for Ticket w/o Time Entries

[CwApiTimeEntrySvc].ReadTimeEntries() - Updated logic to prevent sending CW API request to get empty array/list of timeentries due to the targeting ticket not having any time entries against it.

Upcoming breaking change to the connectwise Rest API.

They will start requiring a generated GUID in the clientId header sometime in Mid-March. This will completely break this module.

I have modified my copy to add the extra parameter. To accomplish this you must modify the following files.
Public\CWSession.ps1

In the param section add a new parameter for ClientID. I added this between PrivateKey and OverrideSSL which ended in my lines 32-35 appearing thus:

    [string]$PrivateKey,
[Parameter(ParameterSetName='Normal', Position=3, Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$ClientID,

Then modify the sections in Begin to include the new ClientID variable, so that that section appears Thus:
Begin
{
[CWApiRestSession] $cwSession = $null;

    if (!$OverrideSSL)
    {
        $cwSession = [CWApiRestSession]::New($Domain, $CompanyName, $PublicKey, $PrivateKey, $ClientID);
    }
    else 
    {
        $cwSession = [CWApiRestSession]::New($Domain, $CompanyName, $PublicKey, $PrivateKey, $ClientID, $true);
    }
}

Then in the Private\PSCWApiClasses.ps1 file Near line 154 I added a line to define the $clientID variable. So the lines immediately following the CWApiRestSession declaration on line 162 now look *thus.
CWApiRestSession ([string] $domain, [string] $companyName, [string] $publicKey, [string] $privateKey, [string] $clientID)
{
$this.Domain = $domain;
$this.CompanyName = $companyName;
$this.PublicKey = $publicKey;
$this.PrivateKey = $privateKey;
$this.clientID = $clientID;

Then in the overload for including the overrideSSL function beginning around line 178 it it also included there.
CWApiRestSession ([string] $domain, [string] $companyName, [string] $publicKey, [string] $privateKey, [string] $clientID, [bool] $overrideSSL)
{
$this.Domain = $domain;
$this.CompanyName = $companyName;
$this.PublicKey = $publicKey;
$this.PrivateKey = $privateKey;
$this.OverrideSSL = $overrideSSL;
$this.ClientID = $clientID;

Then in the definition of the _buildHTTPHeader function, I added the header for clientId. So around line 211-213 it now looks like this:

hidden [void] _buildHttpHeader ()
{
    $this.Header = [hashtable] @{
        "Authorization"    = $this._createCWAuthenticationString();
        "Accept"           = "application/vnd.connectwise.com+json;";
        "Type"             = "application/json";
		"clientId"		   = $this.clientID;
    }

    if ($this.OverrideSSL)
    {
        $this.Header.Add("x-cw-overridessl", "True");
    }
}

That's the end of the changes that I've made to date. It appears to be passing things correctly now, but I won't know for certain how well it works until they start requiring that clientId header.

Build Test are Failing after Last Commit(s)

Fix the 3 failures...

Invoking Pester...
Describing CWCompany
   Context Get-CWCompany
    [+] gets company and checks for the id field 1.08s
    [+] gets company and pipes it through the Select-Object cmdlet for the id property 186ms
    [+] gets the id and subject properties of a company by using the -Property param 159ms
    [+] gets companies by passing array of company ids to the -ID param 427ms
    [+] gets list of companies that were piped to the cmdlet 424ms
    [+] gets company based on the -Filter param 297ms
    [+] gets company based on the -Filter param and uses the SizeLimit param 284ms
    [+] gets companies and sorts company id by descending piping cmdlet through Sort-Object cmdlet 405ms
    [+] wildcard search using Identifier parameter with SizeLimit parameter 776ms
    [+] get single company by Identifier parameter 272ms
    [+] wildcard search using Name parameter with SizeLimit parameter 674ms
    [+] get single company by Name parameter 288ms
    [+] wildcard search using Name parameter with Descending parameter 767ms
Describing CWCompanyContact
   Context Get-CWCompanyContact
    [+] gets a single contact 302ms
    [+] gets company contact entries for a company and check that the results is an array 268ms
    [+] gets a single contact from a company and pipes it through the Select-Object cmdlet for the id property of the first object 250ms
    [+] search for contact by first name 259ms
    [+] gets a single contact 131ms
    [+] search for contact by last name 265ms
    [+] wildcard search for contact by first name 387ms
    [+] wildcard search for contact by last name 376ms
    [+] wildcard search with the Descending parameter 380ms
Describing CWConnectionInfo
   Context Get-CWConnectionInfo
    [+] gets server connection information and checks it for the domain 149ms
Describing CWServiceBoard
   Context Get-CWServiceBoard
    [+] gets board and checks for the id field 266ms
    [+] gets board and pipes it through the Select-Object cmdlet for the id property 119ms
    [+] gets boards by passing array of board ids to the -ID param 520ms
    [+] gets list of boards that were piped to the cmdlet 515ms
    [+] gets board based on the -Filter param 224ms
    [+] gets board based on the -Filter param and uses the SizeLimit param 223ms
    [+] gets boards and sorts board id by descending piping cmdlet through Sort-Object cmdlet 680ms
    [+] wildcard search using Name parameter with SizeLimit parameter 216ms
    [+] get single board by Name parameter 211ms
Describing CWServiceBoardStatus
   Context Get-CWServiceBoardStatus
    [+] gets board status and check that the results is an array 405ms
    [+] gets board and pipes it through the Select-Object cmdlet for the id property of the first object 276ms
Describing CWServiceBoardSubtype
   Context Get-CWServiceBoardSubtype
    [+] gets board status and check that the results is an array 868ms
    [+] gets board and pipes it through the Select-Object cmdlet for the id property of the first object 236ms
Describing CWServiceBoardType
   Context Get-CWServiceBoardType
    [+] gets board status and check that the results is an array 501ms
    [+] gets board and pipes it through the Select-Object cmdlet for the id property of the first object 237ms
Describing CWServiceTicket
   Context Get-CWServiceTicket
    [+] gets ticket and checks for the id field 729ms
    [+] gets ticket and pipes it through the Select-Object cmdlet for the id property 275ms
    [+] gets the id and subject properties of a ticket by using the -Property param 283ms
    [+] gets tickets by passing array of ticket ids to the -ID param 1.1s
    [+] gets list of tickets that were piped to the cmdlet 1.14s
    [+] gets ticket based on the -Filter param 755ms
    [+] gets ticket based on the -Filter param and uses the SizeLimit param 1.14s
    [+] gets tickets and sorts ticket id by descending piping cmdlet through Sort-Object cmdlet 1.12s
    [-] wildcard search using Summary parameter with SizeLimit parameter 14.45s
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 78
      Expected: {True}
      But was:  {False}
      78:           $count -gt 0 -and $count -le $sizeLimit | Should Be $true;
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 78
    [+] get tickets by Summary parameter 4.12s
    [+] wildcard search using Filter parameter with Descending parameter 3.2s
   Context New-CWServiceTicket
    [+] create a new service ticket and check for the ticket number 884ms
   Context Update-CWServiceTicket
    [+] change the subject of a ticket 833ms
WARNING: {
  "code": "InvalidObject",
  "message": "ticket object is invalid",
  "errors": [
    {
      "code": "MissingRequiredField",
      "message": "The summary field is required.",
      "resource": "ticket",
      "field": "summary"
    }
  ]
}
    [-] change the status of a ticket 324ms
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 137
      Expected: {True}
      But was:  {False}
      137:          $ticket.status.id -eq $statusID | Should Be $true; 
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 137
WARNING: {
  "code": "InvalidObject",
  "message": "ticket object is invalid",
  "errors": [
    {
      "code": "MissingRequiredField",
      "message": "The summary field is required.",
      "resource": "ticket",
      "field": "summary"
    }
  ]
}
    [-] change the status of a ticket and set the board ID 310ms
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 146
      Expected: {True}
      But was:  {False}
      146:          $ticket.status.id -eq $statusID -and $ticket.board.id -eq $boardID | Should Be $true; 
      at <ScriptBlock>, C:\Users\Brian\OneDrive\Development\GitHub\PSConnectWise\test\CWServiceTicket.Tests.ps1: line 146
    [+] add a ticket note to a ticket 958ms
   Context Remove-CWServiceTicket
    [+] deletes a ticket and check for a return value of true if successful 1.59s
Describing CWServiceTicketNote
   Context Get-CWServiceTicketNote
    [+] gets ticket note entries for a ticket and check that the results is an array 976ms
    [+] gets a single note from a ticket and pipes it through the Select-Object cmdlet for the id property of the first object 277ms
   Context Add-CWServiceTicketNote
    [+] add a new ticket note to a ticket then checks the return object for the ticket id 376ms
Describing CWSystemMember
   Context Get-CWSystemMember
    [+] gets member and checks for the id field 285ms
    [+] gets member and pipes it through the Select-Object cmdlet for the id property 135ms
    [+] gets members by passing array of member ids to the -ID param 270ms
    [+] gets list of members that were piped to the cmdlet 261ms
    [+] gets member based on the -Filter param 273ms
    [+] gets member based on the -Filter param and uses the SizeLimit param 271ms
    [+] gets members and sorts member id by descending piping cmdlet through Sort-Object cmdlet 265ms
    [+] get member using username parameter via Filter and SizeLimit parameter 263ms
    [+] get single member by First and Last parameters 274ms
    [+] get single member by Username parameter 160ms
Describing CWTimeEntry
   Context Add-CWTimeEntry
    [+] create a new time entry on a ticket 832ms
    [+] create a new time entry on a ticket by passing a hashtable 619ms
    [+] create a new multi-day time entry on a ticket 1s
   Context Get-CWTimeEntry
    [+] gets time entries for a ticket by using the TicketID parameter 568ms
    [+] gets ticket and pipes it through the Select-Object cmdlet for the id property 192ms
    [+] gets list of time entries that were piped to the cmdlet 729ms
    [+] gets tickets and sorts ticket id by descending piping cmdlet through Sort-Object cmdlet 502ms
   Context Update-CWTimeEntry
    [+] change the internal note of a ticket 360ms
    [+] change the status of a ticket and set the board ID 363ms
   Context Remove-CWTimeEntry
What if: Performing the operation "Remove-CWTimeEntry" on target "9311309".
    [+] deletes a ticket and check for a return value of true if successful with the WhatIf parameter 26ms
Describing PrivateHelpers
   Context Split-TimeSpan
    [+] splits time and checks correct number of returned entries 56ms
Tests completed in 56.89s
Passed: 76 Failed: 3 Skipped: 0 Pending: 0 Inconclusive: 0
Completed Test task in task runner.

License Should Be Added

Hello @sgtoj

I looked over the project and I could not find any indication for what license this module was released under.

I'm assuming that the module is intended to be open source and if so you can find help picking one here.

Thanks,
Dakota Clark

Create `CWTimeEntry` Functions

Create function to add time entries. This is because I care about JP.

  • Create Add-CWTimeEntry Advanced Function
  • Create Get-CWTimeEntry Advanced Function
  • Create Remove-CWTimeEntry Advanced Function
  • Created Pester Tests for the Above

CWSession (Replacing Get-CWConnectionInfo)

BREAKING CHANGE

Never thought the Get-CWConnectionInfo was the right name for the function. Session is definitely a better name for the function.

  • Rename Get-CWConnectionInfo to Set-CWSession
  • Rename $Script:CWConnectionInfo to $Script:CWSession
  • Update All Example of the Comment-Based Help
  • Update All Function $Server Parameter to $Session
  • Update All Pester/Unit Tests to Use CWSession
  • Update the Repective API Class
  • Update the README Example
  • Remove Logic for Setting Session within Function
  • Remove Constructors for Setting Session Passing All Value

pageSize object is invalid

Get-CWCompany -Filter 'id>0' -Server $Server | select name

Returns...

WARNING: {
  "code": "InvalidObject",
  "message": "pageSize object is invalid",
  "errors": [
    {
      "code": "OutOfRange",
      "message": "The field pageSize must be between 1 and 100.",
      "resource": "pageSize",
      "field": "pageSize"
    }
  ]
}

Billoption cannot be set to billable (or anything other than Do Not Bill)

Hi all,
I have a script going utilizing the PSConnectWise module
And so far everything is going well, we have automated ticket logging and imports form CSV files - however, we are currently facing an issue with setting the billable option.
When using the integrated switch on the command:
Add-CWTimeEntry
for instance: Add-CWTimeEntry -TicketID $ID -Start $StartTime -End $EndTime -Message $message -MemberID $MemberID -ChargeToType ServiceTicket -BillOption Billable

The bill option doesn't actually get set - and continues to revert to Do Not Bill.
I have gone through the module and replaced all references of DoNotBill (the code reference) and set to billable - this made the whole script break - which i actually found interesting.
and there were a number of other things tested as well.
i just wanted to ask - has anyone else had success setting billable options with this powershell module at all?
Assistance or pointers are appreciated!

i did a string search for all references to BillOption and replaced them with BillableOption - even manually did this (there arent too many - 2 files, Public/CWTimeEntry.ps1 and Private/PSCWApiClasses.ps1 - following this - for SOME reason - this breaks the connection function - Public/CWSession.ps1 which actually has no reference to either of these files - its so bizarre.

Any thoughts at all on this?

Create `Test-CWSession` Function

  • Research to test API resource/endpoint
    • Must be something that is accessible for all members and api-only members.
  • Add TestConnection() method to CWApiRestConnectionInfo
  • Write Test-CWConnection function
  • Write test for the Test-CWConnection function

Deprecated?

I used to run a query to array ticket ids based on a filter (see below). These appears to no longer be working?

$aSR1 = @(Get-CWServiceTicket -Filter "status/name='Acknowledged' and board/id=20 and company/id!=2 and summary not like '%No AV Found' and summary not like '%Standard Services - {Severity1}%' and summary not like '%Critical Event 41' and closedDate>=[ $sYesterday T23:59:59Z]" -Server $oCWServer | select ID)

Import-Module error

Hi,

I am having trouble importing this module onto Windows server 2012 machine. Please see attached error message that I am getting.

I have been able to import the module successfully onto my windows 10 workstation. I have tested it on the workstation and all works fine. However, the import is not working on the server.

This is more of support issue than a bug - hoping someone might be able to assist me.

Thanks!

import-module-error

A few minor typos across the scripts

Thought it might be good to correct these early on to help things down the line:

itemsLeftToRetrived > itemsLeftToRetrieve
queriedCompanys > queriedCompanies

Careful not to do a find/replace on just 'Companys', as you'll catch the CompanySvc variable

Exception Handling

I made big mistake how exceptions are handle. Need to completely review how all exception are handle. Nearly all exceptions need to bubble all the way up. So the consumer of the module can determine how to handle exceptions. This includes for HTTP 4xx and 5xx errors from CW API too.

  • Review Code
  • Determine a Standard
    • All exception will bubble up
    • Except for one gracefully handled.
  • Refactor Code
  • Pass all Existing Tests

Add Support TimeEntries

  • Review CW Dev doc on /time/entries POST request
  • Create UpdateEntry() Method for the TimeEntry Svc
  • Create Update-CWTimeEntry function
  • Create Test

Seucre String with Private key

Hi there,

This is a great module and I am really enjoy using it.

When creating a ConnectWise session is it possible to pass the private key as an secure string? I have tried doing this but the session does not seem to accept the secure string? It does work fine when I pass the private key as a standard string.

Thanks.

Option to Prevent Automatic InternalNote Msg for Time Entires

Provided an option that opts-out of automation notes being added to InternalNote field of a time entry.

Example of Note Being Added:
#1 of 2 Time Entries: 2016-09-13 08:00:00 to 2016-09-13 08:00:00

  • Update the CWAPI... Svc for TimeEntry
  • Update the CWAPI... Svc for TicketNote
  • Update Add-CWTimeEntry
  • Update Add-CWServiceTicketNote
  • Create New Tests the Options

CW Child / Parent Ticket

Any idea how to make a ticket a child ticket? I can't see any example of how that would be done.

Connectwise Manage 2018.4 breaks REST queries using the fields=* parameter

I updated our connectwise manage instance to 2018.4 last night, and found that some queries where I was looking for ServiceboardType by name of the type and the same for service board status weren't working correctly using PSConnectwise.

Through debugging and testing with PostMan I found that connectwise is no longer returning all fields when you specify the fields=* query parameter. Instead it was only returning the ID field. While I feel this is a bug in Connectwise at this point, it's also true that with their API, leaving the fields parameter out completely is the same as fields=*. Given that I modified my local instance of the PSCWAPIClasses.ps1 file in the BuildCWQueryString function, I added another check before it adds the parameter to the vettedqueryparams, where it basically looks for the parameter name fields, and the value to be * and doesn't add it if that is the case.

So that section of code for me now looks like this:
if (![String]::IsNullOrEmpty($p.Value))
{
if ( $p.Key -eq "fields" -and $p.Value -eq "*" )
{
Write-Debug "fields was for all, so leave it out"
}
else
{

				$vettedQueryParams.Add($p.Key, $p.Value);
			}
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.