Import-Module $env:SyncroModule -WarningAction SilentlyContinue
Write-Host "Beginning Admin Password Reset script, ran by $Tech for $Ticket at $Today."
$Username = "Admin"
$group = "Administrators"
[String]$AdminPass = $AdminPass
Write-Host "System Restore Point requested."
Checkpoint-Computer -Description "Admin-Password-Reset" -RestorePointType "MODIFY_SETTINGS"
if ($AdminPass -eq "") {
Write-Host "Admin Password was not specified. Exiting script."
Exit 1
} else {
$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
$existing = $adsi.Children | where {$_.SchemaClassName -eq 'user' -and $_.Name -eq $Username }
if ($existing -eq $null) {
Write-Host "Local Admin account does not already exist. Please run On-Boarding script. Exiting script."
Exit 1
} else {
Write-Host "Setting password for existing local user $Username."
$existing.SetPassword("$AdminPass")
}
Write-Host "Ensuring password for $Username never expires."
& WMIC USERACCOUNT WHERE "Name='$Username'" SET PasswordExpires=FALSE
}
#Ticket notations
Write-Host "Adding Ticket info notations."
Create-Syncro-Ticket-Comment -TicketIdOrNumber $Ticket -Subject "Admin Password Reset" -Body "$AssetName : Created System Restore Point, Reset Admin password" -Hidden "true" -DoNotEmail "true"
Log-Activity -Message "Created System Restore Point & reset Admin password" -EventName "Admin Password Reset"
Write-Host "Script completed."
This kicks out the following error:
error> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
error> HTTP Status: 401 'Unauthorized'
error> Content-Type: 'application/json; charset=utf-8'
error> Response: '{"error":"No ticket"}'
error> Stack:
error> at Invoke-WebRequest20, C:\ProgramData\Syncro\bin\module.psm1: line 326
error> at Call-SyncroApiEx, C:\ProgramData\Syncro\bin\module.psm1: line 253
error> at Call-SyncroApi, C:\ProgramData\Syncro\bin\module.psm1: line 228
error> at Create-Syncro-Ticket-Comment, C:\ProgramData\Syncro\bin\module.psm1: line 174
error> at <ScriptBlock>, C:\ProgramData\Syncro\bin\ec90c69b-3df5-4e97-83ab-0c9cb454a4ad.ps1: line 82
error> at <ScriptBlock>, <No file>: line 1
error> at <ScriptBlock>, <No file>: line 1
error> Call-SyncroApi: failure
error> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
error> HTTP Status: 401 'Unauthorized'
error> Content-Type: 'application/json; charset=utf-8'
error> Response: '{"error":"No ticket"}'
error> Stack:
error> at Invoke-WebRequest20, C:\ProgramData\Syncro\bin\module.psm1: line 326
error> at Call-SyncroApiEx, C:\ProgramData\Syncro\bin\module.psm1: line 253
error> at Call-SyncroApi, C:\ProgramData\Syncro\bin\module.psm1: line 231
error> at Create-Syncro-Ticket-Comment, C:\ProgramData\Syncro\bin\module.psm1: line 174
error> at <ScriptBlock>, C:\ProgramData\Syncro\bin\ec90c69b-3df5-4e97-83ab-0c9cb454a4ad.ps1: line 82
error> at <ScriptBlock>, <No file>: line 1
error> at <ScriptBlock>, <No file>: line 1
error> Call-SyncroApi: failure
Call-SyncroApi: success
Script completed.
As I said, the script worked last week, but doesnât work today. I have initiated it from Edge and from Chrome. I would think it would not matter, as it most likely depends on the machine that is running the script.
If you havenât gotten this resolved yet, one thing comes to mind. Iâve had mixed results with strings embed with a variable in PowerShell in general.
Formatting this way seems to usually work:
â$($AssetName) : Created System Restore Point, Reset Admin passwordâ
I changed $AssetName to $($AssetName) per your suggestion. Still get the exact same error.
It is almost like the call itself with the ticket number isnât working. But even when I donât use $Ticket and instead hard code a ticket number, it still fails.
I tried that, but still get the same errors. See below:
Import-Module $env:SyncroModule
$TicketNum = [convert]::ToInt32($Ticket, 10)
$Today = Get-Date -Format "yyyy-MM-dd_HHmmss"
if ($TicketNum -eq "") {
Write-Host "Beginning RDP-Disable script, ran by $Tech at $Today."
} else {
Write-Host "Beginning RDP-Disable script, ran by $Tech for $TicketNum at $Today."
}
Write-Host "Enabling RDP with firewall configured and requiring NLA."
#Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server'-name "fDenyTSConnections" -Value 0
#Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
#Ticket notations
if ($TicketNum -eq "") {
Write-Host "Ticket number not provided."
} else {
Write-Host "Adding Ticket info notations."
Create-Syncro-Ticket-Comment -TicketIdOrNumber $TicketNum -Subject "RDP" -Body "$($AssetName) : RDP Enabled" -Hidden "true" -DoNotEmail "true"
}
Log-Activity -EventName "RDP"-Message "RDP Enabled"
Write-Host "Script completed."
Slightly different script as I use this to standardize my ticket documentation. If you are willing to try the script, does it work for you? The actual commands are commented out.
From the examples that are at the bottom of the Script pages:
`# This just needs the ticketid or ticket number and you can add a comment. You can have it be "public" or "private", and email or not, and combine those.
# For example you can make a Public comment (shows on PDF/etc) and have it NOT email the customer.
Create-Syncro-Ticket-Comment -TicketIdOrNumber 123 -Subject "Contacted" -Body "This is the comment body here" -Hidden "true/false" -DoNotEmail "true/false"`
This tells me that I should use âtrueâ or âfalseâ, so I believe they should be strings. Any other thoughts?
Parse-Bool is a function that essentially tries to parse -Value from a string into a boolean $true or $false and then returns that, and if it wonât parse - returns -Default
C:\> [bool]::Parse('truE')
True
C:\> [bool]::Parse('false')
False
C:\> [bool]::Parse('shoop')
ERROR # In Parse-Bool, this will return -Default which is $true
C:\> [bool]::Parse($False)
False # Somewhat interestingly, this is taking $False, converting it to the string 'False' and then parsing it back to $False
C:\> [bool]::Parse('0')
ERROR # In Parse-Bool, this will return -Default which is $true
C:> [bool]::Parse(1)
ERROR # In Parse-Bool, this will return -Default which is $true
Somewhat interestingly, this is different from how it would have behaved if they had specified Hidden and DoNotEmail as [bool] types in the powershell function, because then it would have used the implicit typecasting, which operates somewhat counter-intuitively
C:\> [bool]'truE'
True #This seems like it recognizes the word 'true', but
C:\> [bool]'false'
True #Then this would surely be returning False?
C:\> [bool]'shoop'
True #These next couple examples start to show what is happening
C:\> [bool]'0'
True #Essentially any 'string' value will yield 'True'
C:\> [bool]0
False #Powershell does know how to correctly do 0 => False
C:\> [bool]1
True # and 1=> True
C:\> [bool]564
True #OK. Now this is slightly ridiculous! Is every Value "True" unless you know it is "False"
C:\> [bool]$null
False #Ahh! Now things make somewhat more sense. No Value ($null) generated False.
C:\> [bool]$ThisVariableHasNotBeenDefined
False #Ahah!!! Confirmed the $null versus "some value" argument.
Long story short - Use Strings for $Hidden and DoNotEmail - or $True and $False will basically always work too
your second line has a backtick at the end, but I assume thatâs just a small formatting mistake
-DoNotEmail "true/false"`
Interestingly (based on the above Function pulled from the current Module on my computer) - it looks like the endpoint it uses is at /api/syncro_device/tickets/$TicketIdOrNumber/add_comment - which is not listed on the public API Documentation. The closest I see is this one. https://api-docs.syncromsp.com/#/Ticket/post_tickets__id__comment
but being that it is âŚ/syncro_device/tickets/{id}/add_comment and not just /tickets/{id}/comment - maybe the ticket has to be associated to the current device running it?
oop - sorry - I accidentally posted mid-response, but that first message about strings was mainly aimed at Jeremy.
any standard powershell string formats should work great for Hidden and DoNotEmail
$True and $False should also work, but because PowerShell converts them to Strings where needed
So all of these would be examples that would work fine (for that part of the function anyway)
'True'
'false'
"True"
"False"
$True
$false
I am curious if there might be a quirk of how -Body is processed though, causing it to have problems in certain cases.
If you have a moment try this post for me and let me know how it goes.
The asset has to be on the ticket indicated. So, when I would try and reference a ticket that I was working on, and the asset had not been attached to the ticket previously, it would not write to the ticket and just kick out the error.
I need to see if there is a way I can script adding the asset to the ticket prior to writing the comment.
Aha! Looks like the API being tied off /device/ was important!
I think if you wanted to add a device to a Ticket from inside a script - you would probably need to use a ârealâ Syncro REST API key and methods - I donât see anything aimed around adding devices to tickets in the module.
You could make a new ticketand then maybe merge that into your main ticket somewhere else shortly afterward, but I donât think you could add the device to a given ticket from inside the âSyncro Scriptâ
Yeah, I have not seen anything yet on how I can do that.
Is there a way to add assets in mass to a ticket instead of trying to add 50 assets one at a time? It doesnt have to be automated though that wouldnt be a bad thing.
Having it create 50 different tickets and then having to manually merge those would be just as tedious.
Yeah, the only thing that I was thinking with create different tickets and then merge would be if that might be able to be scripted / automated from the technician side.
Sorry for thread necromancy but I too had this issue, found this thread and eventually worked out the fix. You just have to put quotes around the $Ticket variable:
You should not need the quotes since that should be only ever a number. You need quotes if there is a space in the variable. Quotes certainly cannot hurt though.
You cannot run a script on a computer, and then expect it to write to a ticket that does not have that computer on it. That is what my issue was.