Sage 100 BOI Sales Order Script Generator
This generator writes a 32-bit PowerShell script that creates a Sage 100 sales order through the Business Object Interface (BOI), the COM layer Sage 100 itself uses. It covers login, company and module date, task rights, header, one line and Sage's own error text on failure.
Fill in
New-SageSalesOrder.ps1 (run in 32-bit PowerShell)
# Run with: C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -File .\New-SageSalesOrder.ps1
$ErrorActionPreference = 'Stop'
$pvx = New-Object -ComObject ProvideX.Script
$pvx.Init('C:\Sage\Sage 100\MAS90\Home')
$ss = $pvx.NewObject('SY_Session')
$so = $null
try {
if ($ss.nSetUser('BOIUSER', 'ChangeMe1') -ne 1) { throw ('SetUser: ' + $ss.sLastErrorMsg) }
if ($ss.nSetCompany('ABC') -ne 1) { throw ('SetCompany: ' + $ss.sLastErrorMsg) }
[void]$ss.nSetDate('S/O', '20261022')
[void]$ss.nSetModule('S/O')
$task = $ss.nLookupTask('SO_SalesOrder_ui')
if ($ss.nSetProgram($task) -eq 0) { throw ('SetProgram: ' + $ss.sLastErrorMsg) }
$so = $pvx.NewObject('SO_SalesOrder_bus', $ss)
$soNo = '[Sales order number (blank = next number)]'
if ([string]::IsNullOrWhiteSpace($soNo)) {
$next = [ref]''
[void]$so.nGetNextSalesOrderNo($next)
$soNo = $next.Value
}
if ($so.nSetKey($soNo) -eq 0) { throw ('SetKey: ' + $so.sLastErrorMsg) }
if ($so.nSetValue('ARDivisionNo$', '01') -eq 0) { throw ('Division: ' + $so.sLastErrorMsg) }
if ($so.nSetValue('CustomerNo$', 'ABF') -eq 0) { throw ('Customer: ' + $so.sLastErrorMsg) }
$lines = $so.oLines
[void]$lines.nAddLine()
if ($lines.nSetValue('ItemCode$', '1001-HON-H252') -eq 0) { throw ('Item: ' + $lines.sLastErrorMsg) }
if ($lines.nSetValue('QuantityOrdered', [double]'2') -eq 0) { throw ('Qty: ' + $lines.sLastErrorMsg) }
if ($lines.nWrite() -ne 1) { throw ('Line write: ' + $lines.sLastErrorMsg) }
if ($so.nWrite() -ne 1) { throw ('Order write: ' + $so.sLastErrorMsg) }
Write-Output ('Created sales order ' + $soNo)
}
finally {
if ($so -ne $null) { [void]$so.DropObject() }
[void]$ss.nCleanup()
[void]$ss.DropObject()
}Run on a machine with a Sage 100 workstation install (the ProvideX.Script COM server is 32-bit, so 64-bit PowerShell cannot create it). The Sage 100 user needs role rights to Sales Order Entry, and the company may need Allow External Access checked in Company Maintenance. BOI availability depends on your Sage 100 edition and licensing; confirm with your reseller. Methods return 1 for success and 0 for failure (read sLastErrorMsg); nSetKey returns 2 for a new record. If [ref] does not return a number on your setup, fill in the order number field or use the VBScript form: retVal = oSO.nGetNextSalesOrderNo(sNo), which passes by reference natively under 32-bit cscript.exe. Do not store the password in the script in production.
Planning a Sage 100 integration?
Tell us what needs to flow in and out of Sage 100 and we will suggest BOI, VI or read-only access for each piece.
Optional. The tool and every export work without this. No spam.
How to use it
Fill in the MAS90 Home path from the workstation install, a Sage 100 user created for integrations, the company code, the module date and the order data. Leave the order number blank to take the next number from Sales Order Options. Save the output as a .ps1 file and run it with the 32-bit PowerShell in SysWOW64. Test in a copy of the company first. A successful run prints the new order number; a failure throws with the method name and Sage's sLastErrorMsg, for example a customer on hold or an invalid item.
- Use a dedicated Sage 100 user with only the roles the integration needs.
- Keep the module date in YYYYMMDD format.
- Run from the server or a workstation with the same Sage 100 version and product update.
What the calls do
ProvideX.Script Init points the COM server at the Home folder. SY_Session nSetUser and nSetCompany log in, nSetDate and nSetModule set the S/O module date, and nSetProgram with nLookupTask('SO_SalesOrder_ui') applies the security of the Sales Order Entry task, without which the business object refuses to open. SO_SalesOrder_bus is the same object Sales Order Entry uses, so every validation, default and user-defined script runs. nSetKey selects or creates the order, nSetValue sets fields (string fields end in $), oLines is the detail object with nAddLine, nSetValue and nWrite per line, and the header nWrite saves the whole order. DropObject and nCleanup release licences.
API options for Sage 100
On-premise Sage 100 has no native REST API. Integrations use BOI (COM, Windows only), Visual Integrator for file-based imports, ODBC for read-only reporting (or SQL Server reads on Premium) and eBusiness Web Services (SOAP) where installed. REST endpoints for Sage 100 come from third-party connectors that wrap BOI. BOI is the right choice when you need Sage's business rules on write; ODBC or SQL reads are enough for reporting.
Gotchas
Always clean up in finally: an abandoned session can hold a user licence until it times out. A return of 0 from nSetProgram usually means the user lacks rights to the task. PowerShell treats $ inside double quotes as a variable, which is why the script uses single quotes around ItemCode$ and CustomerNo$. Quantities are numeric, so pass a number, not a string. When a user-defined script on the order calls SetError, the header nWrite returns 0 and sLastErrorMsg carries that message.
Frequently Asked Questions
Does Sage 100 have a REST API?
Not natively for on-premise Sage 100. The supported programmatic route is the Business Object Interface (COM), plus Visual Integrator for imports, ODBC for reads and eBusiness Web Services where installed. REST APIs for Sage 100 are provided by third-party connectors, which call BOI underneath, so the same licensing and rights rules apply.
Why does New-Object ProvideX.Script fail in PowerShell?
Most often because the script runs in 64-bit PowerShell and the ProvideX COM server is registered as 32-bit. Run C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe instead. The other cause is a machine without a Sage 100 workstation install, where the COM class is not registered at all.
How do I read the error when nWrite returns 0?
Read sLastErrorMsg on the same object immediately after the failing call, for example $so.sLastErrorMsg after the header write or $lines.sLastErrorMsg after a line write. It holds the same text Sales Order Entry would show the user, such as an invalid item, a credit hold or a user-defined script SetError message.
Why does nSetProgram return 0?
The Sage 100 user you logged in with does not have rights to the task returned by nLookupTask, or the module date and module were not set first. Check the user's roles in Role Maintenance for Sales Order Entry, and call nSetDate and nSetModule for S/O before nSetProgram.
If you want a private assistant that reads Sage 100 orders and drafts entries for approval on your own servers, we can build it on the same BOI layer.
Related Tools
Sage 100 User-Defined Script Generator (VBScript UDS)
Builds a working Sage 100 Advanced or Premium user-defined script that looks up the customer, copies the credit hold flag into a UDF and optionally stops the save.
Other ERPsSage 100 ProvideX Error Codes Reference (Error 12, 43, 65, 88, 200)
Searchable list of the ProvideX run-time errors Sage 100 users actually see, with the exact message text, the usual Sage 100 cause and the first check to run.
Other ERPsSage 100 Table and Module Prefix Reference
Find the Sage 100 module prefix and the commonly used table names for items, customers, vendors, orders and bills of material.
Other ERPsSage 100 Version Upgrade and Data Migration Checklist (2023 to 2025)
A step list for moving Sage 100 Standard, Advanced or Premium to a new major version with a parallel install, covering customizations, reports, integrations and go-live.
More Other ERPs tools
See all- Sage 100 Year-End Close Checklist (Module Order SO, PO, IM, AR, AP, GL)
- Infor VISUAL Work Order Status and Structure Reference
- Infor VISUAL Manufacturing Scheduling Checklist
- Infor XA (MAPICS) Period End Close Checklist
- Infor VISUAL Database Table Reference
- Infor XA (MAPICS) Application Module Reference
- IBM i Commands for Infor XA Administrators Reference
- Acumatica Generic Inquiry Design Template
- Acumatica Manufacturing Edition Setup Checklist
Keep exploring
Free tools
- Sage 100 and Sage 300 Private AI Layer Blueprint GeneratorGenerate an architecture plan for a private AI assistant on on-prem Sage 100 or Sage 300: reporting copy or ODBC extract, Web API or BOI, retrieval, local GPU model and audit.
- Sage 100 Table and Module Prefix ReferenceFind the Sage 100 module prefix and the commonly used table names for items, customers, vendors, orders and bills of material.
- Sage 100 User-Defined Script Generator (VBScript UDS)Builds a working Sage 100 Advanced or Premium user-defined script that looks up the customer, copies the credit hold flag into a UDF and optionally stops the save.
ERP fixes and how-tos
- Sage 100 Business Object Interface (BOI): Working VBScript ExampleWorking Sage 100 BOI pattern: ProvideX.Script, SY_Session logon, nSetCompany, reading a customer and writing records, plus the errors and security settings that break it.
- How to Add AI to Sage 100 and Sage 300 On-PremPrivate AI architecture for on-prem Sage 100 and Sage 300: ODBC or SQL extracts, Sage 300 Web API, Sage 100 BOI, local GPU model, permissions and audit log.
- How to Add User Defined Fields (UDFs) in Sage 100How to add a user defined field in Sage 100 with Custom Office, place it on a panel, and expose it to reports, ODBC and imports, with the usual UDF pitfalls.
AI on your ERP
- AI for Sage 100, Grounded in Your MAS90/200 DataPut AI on Sage 100 and the Sage 100 Manufacturing (MRP) data set without sending data to a public model. Private LLMs and agents grounded in your MAS90/200 tables.
- AI for Sage 100 Small Manufacturers: Practical Answers From Work Orders, BOMs and InventoryPractical AI for small manufacturers on Sage 100: ask about work orders, BOMs, stock and shortages in plain English via ODBC or SQL, kept on a small server.
Integrations
- How to add WhatsApp to Sage 100How to connect WhatsApp to Sage 100 (formerly MAS 90/200): order status, shipment alerts and approvals via the Business Object Interface, ODBC and the Cloud API.
- How to add AI agents to Sage 100How to add AI agents to Sage 100: a tool layer over ODBC and the Business Object Interface, approval-gated writes, and on-prem models for MAS 90/200 shops.