Agente da pasta de rede
Envia os XMLs de saída do servidor interno para o repositório
1. Baixe os três scripts abaixo — eles já saem preenchidos com a URL do app, o token de envio, as pastas \\ASJSERVER\ENVIADOS / \\ASJSERVER\REPOSITORIO e as credenciais de rede.
2. Copie os arquivos para C:\RepoFiscal no servidor que tem as pastas.
As entradas vêm da API da Focus (a chave já está guardada no app); as saídas não usam API — saem da pasta da rede. Se a pasta for outra, rode com -Pasta "E:\ENVIADOS". Guarde os .ps1 em pasta restrita: eles contêm o token e a senha de rede.
3. Agende no Agendador de Tarefas do Windows. Ele envia apenas os XMLs movimentados dentro do mês informado (dia 01 até o último dia do mês, 30, 31 ou 28/29). Cada arquivo já enviado é registrado e não sobe de novo; notas duplicadas também são ignoradas pela chave de acesso.
Prévia (o arquivo baixado vem com URL e token preenchidos).
# Agente de envio das NF de SAIDA -> Repositorio Fiscal
# Roda NO PROPRIO SERVIDOR: le a pasta dos enviados (rede/local, sem API) e
# envia so os XMLs movimentados no mes pedido.
# Ex.: .\enviar-saidas.ps1 -Mes 2026-07 (01 a 31 de julho)
# .\enviar-saidas.ps1 (mes atual)
# .\enviar-saidas.ps1 -Pasta "E:\ENVIADOS" (caminho local no servidor)
param(
[string]$Mes = (Get-Date -Format "yyyy-MM"), # AAAA-MM
[string]$Pasta = "\\ASJSERVER\ENVIADOS", # pasta dos XMLs de saida
[string]$Usuario = "login-as\rootas", # use "" para o login da sessao
[string]$Senha = "atlas104",
[switch]$SemPausa # usado pelas tarefas agendadas
)
$ErrorActionPreference = "Stop"
$Log = "$env:ProgramData\RepoFiscal-log.txt"
function Fim($Codigo) {
Write-Host ""
Write-Host "Log salvo em: $Log" -ForegroundColor DarkGray
if (-not $SemPausa) { Read-Host "Pressione ENTER para fechar" | Out-Null }
exit $Codigo
}
trap {
Write-Host ""
Write-Host "ERRO: $_" -ForegroundColor Red
"$(Get-Date -Format s) ERRO $_" | Out-File -Append -FilePath $Log -Encoding UTF8
Fim 1
}
$Endpoint = "__BASE__/api/public/ingest-saidas"
$Token = "__TOKEN__"
$Enviados = "$env:ProgramData\repo-fiscal-enviados.txt"
# Autentica na pasta (se der erro, tenta o caminho direto com o login da sessao).
$UsouDrive = $false
if ($Usuario -and $Senha) {
try {
$Credencial = New-Object System.Management.Automation.PSCredential(
$Usuario, (ConvertTo-SecureString $Senha -AsPlainText -Force))
if (Get-PSDrive -Name SAIDAS -ErrorAction SilentlyContinue) { Remove-PSDrive -Name SAIDAS -Force }
New-PSDrive -Name SAIDAS -PSProvider FileSystem -Root $Pasta -Credential $Credencial -Scope Script -ErrorAction Stop | Out-Null
$Pasta = "SAIDAS:\"
$UsouDrive = $true
} catch {
Write-Host "Sem mapear drive, lendo direto: $Pasta" -ForegroundColor Yellow
}
}
if (!(Test-Path $Pasta)) { Write-Host "Pasta nao encontrada: $Pasta" -ForegroundColor Red; Fim 1 }
# Janela do mes: dia 01 00:00 ate o ultimo dia 23:59:59 (30, 31 ou 28/29)
$Inicio = [datetime]::ParseExact("$Mes-01", "yyyy-MM-dd", $null)
$Fim = $Inicio.AddMonths(1)
if (!(Test-Path $Enviados)) { New-Item -ItemType File -Path $Enviados -Force | Out-Null }
$Historico = Get-Content $Enviados
$Arquivos = @(Get-ChildItem -Path $Pasta -Filter *.xml -Recurse -File |
Where-Object { $_.LastWriteTime -ge $Inicio -and $_.LastWriteTime -lt $Fim } |
Where-Object { $Historico -notcontains $_.FullName })
Write-Host "Mes $Mes : $($Arquivos.Count) arquivo(s) movimentado(s) para enviar"
for ($i = 0; $i -lt $Arquivos.Count; $i += 50) {
$Bloco = $Arquivos[$i..([math]::Min($i + 49, $Arquivos.Count - 1))]
$Payload = @{
tipo = "saida"
arquivos = @($Bloco | ForEach-Object {
@{ nome = $_.Name; xml = (Get-Content $_.FullName -Raw -Encoding UTF8) }
})
} | ConvertTo-Json -Depth 5
$Resposta = Invoke-RestMethod -Uri $Endpoint -Method Post -ContentType "application/json; charset=utf-8" `
-Headers @{ "x-ingest-token" = $Token } -Body ([System.Text.Encoding]::UTF8.GetBytes($Payload))
if ($null -eq $Resposta.novas) {
Write-Host "O endpoint nao respondeu como esperado (nada foi gravado)." -ForegroundColor Red
Write-Host "URL usada: $Endpoint" -ForegroundColor Yellow
Write-Host "Baixe os scripts de novo no painel e tente outra vez." -ForegroundColor Yellow
Fim 1
}
Write-Host "Enviados: $($Resposta.novas) novas / $($Resposta.ignoradas) ignoradas"
$Bloco | ForEach-Object { Add-Content -Path $Enviados -Value $_.FullName }
}
Write-Host "Concluido. Agora rode: .\baixar-mes.ps1 -Mes $Mes" -ForegroundColor Green
if ($UsouDrive) { Remove-PSDrive -Name SAIDAS -Force }
Fim 0
Salve como baixar-mes.ps1 no servidor. Ele baixa todos os XMLs de um mês (entradas e saídas) para \\ASJSERVER\REPOSITORIO\2026-07, criando a subpasta do mês automaticamente e ignorando o que já existe.
# Espelha os XMLs do repositorio para a pasta de rede, por mes
# Ex.: .\baixar-mes.ps1 -Mes 2026-07 (entradas + saidas)
# .\baixar-mes.ps1 -Mes 2026-08 -Tipo saida
param(
[Parameter(Mandatory=$true)][string]$Mes, # AAAA-MM
[string]$Tipo = "todos", # todos | entrada | saida
[string]$Destino = "\\ASJSERVER\REPOSITORIO",
[string]$Usuario = "login-as\rootas", # use "" para o login da sessao
[string]$Senha = "atlas104",
[switch]$SemPausa
)
$ErrorActionPreference = "Stop"
$Log = "$env:ProgramData\RepoFiscal-log.txt"
function Fim($Codigo) {
Write-Host ""
Write-Host "Log salvo em: $Log" -ForegroundColor DarkGray
if (-not $SemPausa) { Read-Host "Pressione ENTER para fechar" | Out-Null }
exit $Codigo
}
trap {
Write-Host ""
Write-Host "ERRO: $_" -ForegroundColor Red
"$(Get-Date -Format s) ERRO $_" | Out-File -Append -FilePath $Log -Encoding UTF8
Fim 1
}
$Endpoint = "__BASE__/api/public/exportar-mes"
$Token = "__TOKEN__"
$UsouDrive = $false
if ($Usuario -and $Senha) {
try {
$Credencial = New-Object System.Management.Automation.PSCredential(
$Usuario, (ConvertTo-SecureString $Senha -AsPlainText -Force))
if (Get-PSDrive -Name REPO -ErrorAction SilentlyContinue) { Remove-PSDrive -Name REPO -Force }
New-PSDrive -Name REPO -PSProvider FileSystem -Root $Destino -Credential $Credencial -Scope Script -ErrorAction Stop | Out-Null
$Destino = "REPO:\"
$UsouDrive = $true
} catch {
Write-Host "Sem mapear drive, gravando direto: $Destino" -ForegroundColor Yellow
}
}
if (!(Test-Path $Destino)) { New-Item -ItemType Directory -Path $Destino -Force | Out-Null }
$Body = @{ mes = $Mes; tipo = $Tipo } | ConvertTo-Json
$Resposta = Invoke-RestMethod -Uri $Endpoint -Method Post -ContentType "application/json" `
-Headers @{ "x-ingest-token" = $Token } -Body $Body
if ($null -eq $Resposta.total) {
Write-Host "O endpoint nao respondeu como esperado." -ForegroundColor Red
Write-Host "URL usada: $Endpoint" -ForegroundColor Yellow
Write-Host "Baixe os scripts de novo no painel e tente outra vez." -ForegroundColor Yellow
Fim 1
}
Write-Host "Mes $($Resposta.mes): $($Resposta.total) arquivo(s)"
foreach ($Arquivo in $Resposta.arquivos) {
$Pasta = Join-Path $Destino $Arquivo.pasta
if (!(Test-Path $Pasta)) { New-Item -ItemType Directory -Path $Pasta -Force | Out-Null }
$Caminho = Join-Path $Pasta $Arquivo.nome
if (Test-Path $Caminho) { continue }
Invoke-WebRequest -Uri $Arquivo.url -OutFile $Caminho
}
Write-Host "Concluido em $Destino" -ForegroundColor Green
if ($UsouDrive) { Remove-PSDrive -Name REPO -Force }
Fim 0
Salve os três arquivos em C:\RepoFiscal no servidor e depois clique com o botão direito em instalar-agente.ps1 → Executar com o PowerShell (como Administrador). Ele cria duas tarefas diárias: uma envia as saídas de \\ASJSERVER\ENVIADOS e a outra espelha o mês em \\ASJSERVER\REPOSITORIO\AAAA-MM. Nenhum instalador .exe é necessário.
# Instalador do agente fiscal - cria as tarefas agendadas no Windows
# Clique com o botao direito neste arquivo -> "Executar com o PowerShell" (como Administrador)
param(
[string]$Pasta = "C:\RepoFiscal", # onde ficam os .ps1
[string]$Hora = "20:00", # horario da execucao diaria
[switch]$SemPausa
)
$ErrorActionPreference = "Stop"
$Log = "$env:ProgramData\RepoFiscal-log.txt"
function Fim($Codigo) {
Write-Host ""
Write-Host "Log salvo em: $Log" -ForegroundColor DarkGray
if (-not $SemPausa) { Read-Host "Pressione ENTER para fechar" | Out-Null }
exit $Codigo
}
trap {
Write-Host ""
Write-Host "ERRO: $_" -ForegroundColor Red
"$(Get-Date -Format s) ERRO $_" | Out-File -Append -FilePath $Log -Encoding UTF8
Fim 1
}
$Admin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $Admin) {
Write-Host "Precisa rodar como ADMINISTRADOR." -ForegroundColor Red
Write-Host "Feche, clique com o botao direito no PowerShell -> Executar como administrador, e rode de novo." -ForegroundColor Yellow
Fim 1
}
if (!(Test-Path $Pasta)) { New-Item -ItemType Directory -Path $Pasta -Force | Out-Null }
$Enviar = Join-Path $Pasta "enviar-saidas.ps1"
$Baixar = Join-Path $Pasta "baixar-mes.ps1"
foreach ($Arquivo in @($Enviar, $Baixar)) {
if (!(Test-Path $Arquivo)) {
Write-Host "FALTA: $Arquivo - copie os 3 scripts para $Pasta antes de continuar." -ForegroundColor Yellow
Fim 1
}
}
# Tarefa 1: sobe as saidas da pasta de enviados (mes atual), rodando no servidor
$AcaoEnviar = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$Enviar`" -SemPausa"
# Tarefa 2: espelha o mes atual em \\ASJSERVER\REPOSITORIO\<AAAA-MM>
$AcaoBaixar = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -Command `"& '$Baixar' -Mes (Get-Date -Format 'yyyy-MM') -SemPausa`""
$Gatilho1 = New-ScheduledTaskTrigger -Daily -At $Hora
$Gatilho2 = New-ScheduledTaskTrigger -Daily -At ([datetime]::Parse($Hora).AddMinutes(20).ToString("HH:mm"))
$Config = New-ScheduledTaskSettingsSet -StartWhenAvailable -MultipleInstances IgnoreNew
Register-ScheduledTask -TaskName "RepoFiscal - Enviar saidas" -Action $AcaoEnviar `
-Trigger $Gatilho1 -Settings $Config -RunLevel Highest -Force | Out-Null
Register-ScheduledTask -TaskName "RepoFiscal - Baixar mes" -Action $AcaoBaixar `
-Trigger $Gatilho2 -Settings $Config -RunLevel Highest -Force | Out-Null
Write-Host "Tarefas criadas:" -ForegroundColor Green
Write-Host " RepoFiscal - Enviar saidas ($Hora, todos os dias)"
Write-Host " RepoFiscal - Baixar mes ($($Gatilho2.StartBoundary.Substring(11,5)), todos os dias)"
Write-Host ""
Write-Host "Para testar agora sem esperar:"
Write-Host " Start-ScheduledTask -TaskName 'RepoFiscal - Enviar saidas'"
Write-Host " Start-ScheduledTask -TaskName 'RepoFiscal - Baixar mes'"
Fim 0