2017-07-17 1 views
0

J'avais préparé un script pour tirer un certain rapport w.r.t serveur SQL et out put sera poussé vers différentes feuilles CSV. Une fois la sortie générée, tous les fichiers CSV sont fusionnés en un seul fichier Excel à l'aide de la fonction personnalisée et Excel sera envoyé à mon adresse e-mail. En cours d'exécution de htrough powershell_ise.exe, il fonctionne correctement et je reçois le courrier électronique avec succès. Lorsque j'ai programmé le même script, je reçois le mail mais sans les pièces jointes Excel. Je suspecte que la fonction créée par coutume n'est pas utilisée, parce que je ne vois aucun dossier excel converti dans l'endroit désiré.Power Shell fonction personnalisée dans le script

J'ai essayé tous les moyens possibles, comme le point sourcing, en collant la fonction dans le script lui-même mais pas de chance. Je suis un débutant en PowerShell, peut-on s'il vous plaît aidez-moi s'il me manque quelque chose.

Merci, Anil

Function Merge-CSVFiles 
{ 
Param(
$CSVPath = "D:\Anil\Missing_Indexes", ## Soruce CSV Folder 
$XLOutput="D:\Anil\Missing_Indexes.xls" ## Output file name 
) 

$csvFiles = Get-ChildItem ("$CSVPath\*") -Include *.csv 
$Excel = New-Object -ComObject excel.application 
$Excel.visible = $false 
$Excel.sheetsInNewWorkbook = $csvFiles.Count 
$workbooks = $excel.Workbooks.Add() 
$CSVSheet = 1 

Foreach ($CSV in $Csvfiles) 

{ 
$worksheets = $workbooks.worksheets 
$CSVFullPath = $CSV.FullName 
$SheetName = ($CSV.name -split "\.")[0] 
$worksheet = $worksheets.Item($CSVSheet) 
$worksheet.Name = $SheetName 
$TxtConnector = ("TEXT;" + $CSVFullPath) 
$CellRef = $worksheet.Range("A1") 
$Connector = $worksheet.QueryTables.add($TxtConnector,$CellRef) 
$worksheet.QueryTables.item($Connector.name).TextFileCommaDelimiter = $True 
$worksheet.QueryTables.item($Connector.name).TextFileParseType = 1 
$worksheet.QueryTables.item($Connector.name).Refresh() 
$worksheet.QueryTables.item($Connector.name).delete() 
$worksheet.UsedRange.EntireColumn.AutoFit() 
$CSVSheet++ 

} 

$workbooks.SaveAs($XLOutput,51) 
$workbooks.Saved = $true 
$workbooks.Close() 
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbooks) | Out-Null 
$excel.Quit() 
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null 
[System.GC]::Collect() 
[System.GC]::WaitForPendingFinalizers() 

} 
+2

Nous aurons besoin de plus de détails sur la fonction qui interagit avec Excel, et comment vous avez configuré la tâche planifiée (quel compte est-il en cours d'exécution, quels paramètres sont sur la tâche, etc.) –

+2

MathiasR.Jessen a dit. Cependant, je soupçonne que votre fonction est simplement référencée avant d'être définie dans le script. Assurez-vous que vos fonctions sont définies dans la portée, avant qu'elles ne soient référencées. –

+0

@JacobColvin Ce n'est pas une mauvaise idée, c'est un piège classique de powershell_ise ;-) –

Répondre

0

Lors de l'exécution par powershell_ise.exe, il tourne bien et je reçois l'e-mail avec succès

En effet, l'ISE sur votre boîte est capable de charger votre fonction personnalisée pendant l'exécution et générer le rapport.

Mais lorsque cela est planifié à l'aide d'un travail, le script s'exécutera sur un serveur différent de votre boîte, par conséquent le script ne pourra pas trouver la fonction et vous n'obtiendrez pas le rapport.

J'ai rencontré ce genre de problème avant d'utiliser des fonctions personnalisées. Le travail autour de ce que je peux suggérer est l'emballage pour les fonctions personnalisées dans un module séparé et l'importation du module dans votre script principal. (De préférence, sauvegardez le module au même endroit que votre script pour faciliter le dépannage).

Exemple: Enregistrer votre fonction dans un fichier module .psm1

Function ScriptExample { 
Param ([string] $script, 
     [string] $jobname, 
     [string] $jobcategory, 
     [hashtable] $config, 
     [string] $deletelogfilepath, 
     [string] $servername) 



#your-function-here# 
{ 
    } 

Return $script; 

}

appeler maintenant ce module dans votre script principal comme suit,

$importmoduleroot = "C:\temp\SO_Example.psm1" 

###### LOAD MODULES ###### 

# Import all related modules written to support this process 
$modules = get-childitem -path $importmoduleroot -include SO*.psm1 -recurse; 

Vous pouvez ensuite appeler votre fonction et transmettre les paramètres dans le script principal,

ScriptExample -script $script ` 
      -jobname $jobname ` 
      -jobcategory $jobcategory ` 
      -config $config ` 
      -servername $ServerName ` 
      -deletelogfilepath $deletelogfilepath 
+0

@MK Pouvez-vous s'il vous plaît me fournir des étapes dans les détails pour faire les changements nécessaires ou un exemple si vous avez. – user6849192

+0

Merci pour les étapes MK. J'ai créé la fonction personnalisée en tant que module et j'avais appelé la même chose dans mon script. Je n'ai pas été capable de comprendre complètement l'exemple ci-dessous. Pouvez-vous s'il vous plaît expliquer l'exemple en détail – user6849192