VisualCron AB

VisualCron → Apache Airflow

VisualCron has been a pragmatic Windows scheduler for two decades — but as workloads move to Linux containers and cloud, BatchFoundry converts your Tasks, Triggers, Variables, and Job Chains into clean Airflow DAGs.

VisualCron is a mature Windows-centric automation platform used widely in SME and mid-market enterprises. Its GUI-driven job authoring, rich trigger library, and nested variable substitution make it flexible on-premises — but those same characteristics become friction when an organization moves toward Kubernetes, cloud-native data platforms, and open-source orchestration. BatchFoundry handles the full VisualCron-to-Airflow migration: XML export, trigger analysis, credential migration, and a 14-day parallel-execution comparison before cutover.

Concept Mapping

JobDAG
TaskTask / Operator
Time Triggerschedule_interval (cron string)
File TriggerFileSensor / S3KeySensor
Folder TriggerFileSensor with glob pattern
Database TriggerBashOperator polling pattern
Job ChainTask dependency chain (>>)
Conditional TaskBranchPythonOperator
Variable ({Date.Now})Jinja template / XCom value
CredentialAirflow Connection (Vault backend)
Retry policyretries + retry_delay in default_args
Notification TaskEmailOperator / on_failure_callback

The Hard Parts We Handle

  • File, Folder, and Database Triggers have no 1:1 Airflow equivalent — each is mapped to the most appropriate Sensor pattern
  • Nested variable substitution (e.g. {Server.IP}, {Date.Now('yyyyMMdd')}) expanded into Jinja templates or XCom values
  • Job Chain conditional branching ('if exit code = X') becomes BranchPythonOperator with explicit task_ids
  • VisualCron Credentials migrated to Airflow Connections with Vault / Secrets Manager backends recommended
  • Windows-only execution model rehosted to Linux BashOperator or SSHOperator targeting existing Windows agents
  • Per-server licensing audit before cutover to validate host counts

VisualCron Job to Airflow DAG

Before

<!-- VisualCron Job: Daily Sales ETL -->
<Job Name="Daily_Sales_ETL">
  <Trigger Type="Time" Schedule="Daily 02:00" />
  <Tasks>
    <Task Type="Execute" Path="C:\etl\extract.bat" />
    <Task Type="Execute" Path="C:\etl\transform.bat" />
    <Task Type="SendEmail" To="ops@example.com" />
  </Tasks>
</Job>

After (Airflow)

# Airflow DAG: daily_sales_etl
from airflow.decorators import dag
from airflow.operators.bash import BashOperator
from airflow.operators.email import EmailOperator
from pendulum import datetime

@dag(schedule="0 2 * * *", start_date=datetime(2025, 1, 1), catchup=False)
def daily_sales_etl():
    extract = BashOperator(task_id="extract",
                           bash_command="/etl/extract.sh")
    transform = BashOperator(task_id="transform",
                             bash_command="/etl/transform.sh")
    notify = EmailOperator(task_id="notify",
                           to="ops@example.com",
                           subject="Daily sales ETL complete",
                           html_content="OK")
    extract >> transform >> notify

daily_sales_etl()

Ready to migrate from VisualCron?

Talk to a BatchFoundry engineer about your workload estate.

Talk to an Engineer

Related Migrations