XMLGO

Agente da pasta de rede

Envia os XMLs de saída do servidor interno para o repositório

Voltar ao repositório
Como funciona

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.

Script PowerShell — saídas de \\ASJSERVER\ENVIADOS (por mês)

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
Script PowerShell — salvar o mês na pasta \\ASJSERVER\REPOSITORIO

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
Instalador — cria as tarefas agendadas sozinho

Salve os três arquivos em C:\RepoFiscal no servidor e depois clique com o botão direito em instalar-agente.ps1Executar 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