Copied job between servers has ID of different job! - VisualCron - Forum

Community forum

keithdavis
2018-10-14T21:48:31Z
I've never had this happen before, but I recently copied a job from one server to another and that copied job had the same ID as different job on the destination server. Is there nothing that checks to make sure that does not happen? Is that always a risk?
keithdavis
2018-10-19T03:47:30Z
I can confirmed this happens by modifying and copying the default VisualCron log cleanup job to a different server and watched it overwrite. I wonder how many times in the past this has happened? I guess if it was a random collision, then probably very low chance, but can we not get a confirmation before overwrite?
Support
2018-10-19T09:54:14Z
Random collisions are impossible because the use of GUIDs. Normally we call this a feature so you can have a test and prod environment. When copied over you get the same id. This way, next time when you update the Job in test and move to Prod it is updated.
Henrik
Support
http://www.visualcron.com 
Please like  VisualCron on facebook!
keithdavis
2018-10-22T22:08:27Z
Ok, that's fine for the one that I know SHOULD be the same GUID, but not for the one that I created a copied over a job that never existed on the server I copied it to (a newly created job). I get that the GUID conflict is impossible, but someone it ended up with the same GUID of a different job.
Gary_W
2019-01-11T16:23:38Z
I just saw this post. I have been burned by this same issue several times when moving jobs between servers and have submitted a suggestion to warn when copying if the job or task ID exists already and to give the option to copy with a new ID. In the meantime, just the other day I stumbled on some powershell code that uses the API to connect to the server via AD, loops through jobs to make changes and then saves the job. I tweaked the code (I know enough powershell to be dangerous) to allow one to pass in a job/task ID and it will search the server and respond if the ID exists or not in order to let you know if it is safe to copy the job. Since I'm not the only one with this issue I'll share this until the VC folks address this properly. Previous to this I was searching for the job/task IDs in the jobs.xml file in the backup.zip file.

I have a group with utility jobs, and added one called "Search if Job/Task ID is in use on this server". It consists of 3 tasks, an interactive popup to ask for an ID (writes it to STDOUT), the powershell task, and another popup to display results although the powershell task writes to its STDOUT so the last popup is not really needed.

I wish I saved the original author's name in order to give credit where credit is due, but here's the powershell code. Let me know if it's useful for you!
I'd attach the exported job, but imagine the embarrassment if it's ID overwrote something important when it was imported! lol
================= Start =======================

##
## SearchIDs - Searches Job and Task IDs for the passed-in ID. Outputs an appropriate message
##
## Params: JobIDIn Value: {TASK(PrevTask|StdOut)} (output from the popup; the ID to search for)
##
Param(
[string] $jobIDIn
)

# Get-VCAPIPath will get the path for VisualCron API DLLs
function Get-VCAPIPath
{
$programFilesPath = if (${Env:PROCESSOR_ARCHITECTURE} -eq 'x86') { ${Env:ProgramFiles} } else { ${Env:ProgramFiles(x86)} }
Join-Path $programFilesPath VisualCron\VisualCronAPI.dll
}

# Get-VCServer allows you to connect to the VisualCron Server
function Get-VCServer
{
[CmdletBinding()]
param ([string]$ComputerName,
[int]$Port,
[System.Management.Automation.PSCredential]$Credential)

$apiPath = Get-VCAPIPath
if (!(Test-Path $apiPath)) { Throw "VisualCron does not appear to be installed. API library not found at `"$apiPath`"." }
[Reflection.Assembly]::LoadFrom($apiPath) | Out-Null
$conn = New-Object VisualCronAPI.Connection
$conn.Address = if ([String]::IsNullOrEmpty($ComputerName)) { ${Env:COMPUTERNAME} } else { $ComputerName }
if (!($credential -eq $null))
{
$conn.UseADLogon = $true
$netcred = $credential.GetNetworkCredential()
$conn.UserName = $netcred.UserName
$conn.Password = $netcred.Password
}
$client = New-Object VisualCronAPI.Client
$client.Connect($conn)
}

# Get-AllVCJobs returns a list of all the jobs in VisualCron server for the current machine
function Get-AllVCJobs
{
[CmdletBinding()]
param ([string]$ComputerName,
[int]$Port,
[System.Management.Automation.PSCredential]$Credential,
[switch]$Active)

$ps = New-Object Collections.Hashtable($psBoundParameters)
$ps.Remove('Active') | Out-Null
# Connect to the Server
$server = Get-VCServer @ps
# Get all the jobs
$server.Jobs.GetAll() `
| ? { !($Active) -or $_.Stats.Active } `
| Add-Member ScriptMethod Start { $server.Jobs.Run($this, $false, $false, $false, $null) }.GetNewClosure() -PassThru
}

# SearchIDs will look for job OR task ID's that match what was passed in.
function SearchIDs
{
[CmdletBinding()]
param ([string]$ComputerName,
[int]$Port,
[System.Management.Automation.PSCredential]$Credential,
[switch]$Active)

$ps = New-Object Collections.Hashtable($psBoundParameters)
$ps.Remove('Active') | Out-Null
# Connect to the VisualCron server
$server = Get-VCServer @ps

# Get all the jobs
$jobs = Get-AllVCJobs
Foreach ($job in $jobs)
{
$tasks = $job.Tasks # Get the Jobs' Tasks
Foreach ($task in $tasks)
{
if ($jobIDIn -eq $job.Id -or $jobIDIn -eq $task.Id)
{
Write-Output ("ID exists! Job: " + $job.Name + ", Job ID: " + $job.Id + ", Task: " + $task.Name + ", Task ID: " + $task.Id )
return
}
}
}
Write-Output ("Copy at will!")
return
}

SearchIDs

===================== END ===========================
Scroll to Top