2017-11-17 5 views
0

だから私は私のスクリプトでこのループを持っている:スピードアップPowerShellスクリプトを(起動-SQLCMDとWordオブジェクトを)

foreach ($candID in Get-Content $candList) 
{ 
    $candID = $candID -replace '\s','' 
    $candID 

    $templateDir = Get-ChildItem ($ScriptPath + "Templates\Resumes\") | Get-Random -Count 1 
    $templateFile = $templateDir 
    $templateDir = ($ScriptPath + "Templates\Resumes\" + $templateDir) 

    $lname = Invoke-Sqlcmd -Query "SELECT LEFT(personFirstName, 1) FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 

    $firstname = Invoke-Sqlcmd -Query "SELECT personFirstName FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $surname = Invoke-Sqlcmd -Query "SELECT personSurname FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Address1 = Invoke-Sqlcmd -Query "SELECT CandidateAddress FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $City  = Invoke-Sqlcmd -Query "SELECT CandidateCity FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Postcode = Invoke-Sqlcmd -Query "SELECT CandidatePostcode FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $Mobile = Invoke-Sqlcmd -Query "SELECT personMobileTelephone FROM tblPErson WHERE personID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 
    $State  = Invoke-Sqlcmd -Query "SELECT CandidateState FROM tblCandidate WHERE CandidateID = $candID" -serverinstance $ServerAddress -Database $DatabaseName 

    $firstname = $firstname.ItemArray[0] 
    $surname = $surname.ItemArray[0] 
    $Address1 = $Address1.ItemArray[0] 
    $City  = $City.ItemArray[0] 
    $Postcode = $Postcode.ItemArray[0] 
    $Mobile = $Mobile.ItemArray[0] 
    $State  = $State.ItemArray[0] 
    $lName  = $lName.ItemArray[0] 

    cls 

    ### Loop Visual 
    Write-Host "" 
    Write-Host "Generating resumes" -ForegroundColor Cyan 
    Write-Host " ---------------------------------------------------------------------------------------------------- " 
    Write-Host "" 
    Write-Host "" 
    Write-Host "Using resume template: $templateFile" -foregroundColor GREEN 
    Write-Host "" 
    Write-Host "Data:" 

    Write-Host " Firstname = $firstname" 
    Write-Host " surname  = $surname" 
    Write-Host " Address1 = $Address1" 
    Write-Host " City  = $City"  
    Write-Host " Postcode = $Postcode" 
    Write-Host " Mobile  = $Mobile" 
    Write-Host " State  = $State"  

    ### End Loop Visual 

    $filename = ($firstname + " " + $surname + " - " + $candID + ".doc") 
    $filename2 = ($firstname + " " + $surname + " - " + $candID + ".txt") 

    $saveAs = ($scriptPath + "Documents\Original Resumes\" + $lName + "\" + $filename) 
    $saveAs2 = ($scriptPath + "Documents\Original Resumes\" + $lName + "\" + $filename2) 

    $objWord = New-Object -comobject Word.Application 
    $doc=$objWord.documents.Add($templateDir) 
    $objWord.Visible = $false 
    $doc.Bookmarks.Item("Address1").Range.Text = $Address1 
    $doc.Bookmarks.Item("firstName").Range.Text = $firstname 
    $doc.Bookmarks.Item("surName").Range.Text = $surname 
    $doc.Bookmarks.Item("City").Range.Text = $City 
    $doc.Bookmarks.Item("Postcode").Range.Text = $Postcode 
    $doc.Bookmarks.Item("Mobile").Range.Text = $Mobile 
    $doc.Bookmarks.Item("State").Range.Text = $State 
    $doc.SaveAs([REF]$saveAs) 
    $doc.Close() 

    $doc2=$objWord.documents.Add($saveAs) 
    $doc2.SaveAs([REF]$saveAs2, [REF] 2) 

    $objWord.Quit() 
} 

は基本的に、私は、Wordテンプレートを使用して、データベース内のレコードのための偽装履歴書を作成しています。スクリプトは機能しますが、5秒ごとに約2〜3回の再開を作成するだけですが、これはデータベース全体(100万の偽装レコード)を満たす必要があるため、少し問題です。

さらに、テンプレートをランダムに作成するのではなく、人の業種に合わせてカスタマイズできるようになり、各レジ​​ュームにさらに多くのデータを追加するので、時間がかかります、参考文献など)。

少し速くするためにできることはありますか?

+2

第一のものは、1つの文にあなたのSQLを減らすことであろう。 1つのクエリで各値をクエリする必要はありません。それを一つに持っていく。 '$ objWord'を作成するだけでよいのです。ループの外側で一度初期化します。外でも終了します。あなたがそれを避けることができれば、コンソールに情報を書き込む時間を無駄にしません。それは遅いです。ロギングしたい場合はファイルに入れます。 – Matt

+0

ありがとう!その際、各値はアイテム配列内の異なる数値になりますか?姓はsqlResult.ItemArray [1]ですか? –

+0

これらすべての変更を加えたところ、5秒ごとに7 - 8になりました。すべての履歴書を作成するのにまだ8日かかりますが、それは20より良いでしょう。 –

答えて

0

最初の手順は、PowerShell 3.0以降でこのスクリプトを実行することです。オフィスのCOMオブジェクトは、PowerShell 2.0のパフォーマンスが低いことで知られており、スクリプトを編集することなく、より高速に実行される可能性があります。

スクリプト全体としては、SQL Serverからデータを取得する部分を調整します。あなたがコメントしたように、これを1つの呼び出しにすることができます。サンプルデータを有するか、$candListで、そのファイルが実際に含まれているものを知らなくても、あなたはあなたのスクリプトの上半分を作ることができます

このような何か:

$candData = Get-Content $candList -Raw | ForEach-Object {$_ -replace '\s',''} 

$qry = " 
    SELECT personFistName, 
     LEFT(personFirstName, 1) AS personLastName, 
     personSurname, 
     CandidateAddress, 
     CandidateCity, 
     CandidatePostcode, 
     personMobileTelephone, 
     CandidateState 
    FROM tblCandidate 
    WHERE personID IN ($($candData -split ',')); 
" 
$templateDir = Get-ChildItem ($ScriptPath + "Templates\Resumes\") | Get-Random -Count 1 
$templateFile = $templateDir 
$templateDir = ($ScriptPath + "Templates\Resumes\" + $templateDir) 

$data = Invoke-SqlCmd -ServerInstance $ServerAddress -Database $DatabaseName -Query $qry 

foreach ($row in $data) { 
    $lname = $row.personLastName 
    $firstname = $row.personFirstName 
    $surname = $row.personSurname 
    $Address1 = $row.CandidateAddress 
    $City  = $row.CandidateCity 
    $Postcode = $row.CandidatePostcode 
    $Mobile = $row.personMobileTelephone 
    $State  = $row.CandidateState 
+0

私はこれでちょっと混乱します。申し訳ありませんが、私は比較的PowerShellを初めて使っています。これは、データベース内のすべての行をオブジェクトに保存するだけですか? $ 1000000行のいくつかの問題が$ dataに格納されていませんか? –

+0

ちょうどこれを試してもうまくいきませんでしたが、candListファイルは改行で区切られたIDのリストです。 Microsoft.SqlServer.Management.PowerShell.SqlPowerShellSqlExecutionException: '1330002'の近くの構文が正しくありません。 ---> System.Data.SqlClient.SqlException: '1330002'の近くの構文が正しくありません。 –

関連する問題