PowerShell script slows down during for loop
$begingroup$
I'm rather new to PowerShell so I could use some help with why my script is running so slow. It starts off just fine, and even the first 30 or so iterations of the for loop are zippy. But by the time my for
loop gets to around 75 iterations, it has slowed down to ~20 seconds per iteration. Do I need to do some garbage collection? Any insight is much appreciated!
Since you obviously don't have the files I'm working with, here are some details:
- my excel file is 342 lines
- my image folder contains 50 images
- an example of the matching I'm doing would be color: WEATHERED BLEND image: NovikShake_HS_WeatheredBlend.jpg
######################################################################################################################
# manually enter these values:
$vendorName = 'CompanyX'
$saveAsName = "CompanyX Items $(get-date -f yyyy-MM-dd).xlsx"
$sheetName = 'Items'
$colorColumn = 'G'
$colorSwatchImageHyperlinkColumn = 'Y'
######################################################################################################################
#progress bar function
$progressBar = @{
Activity = "Processing $vendorName file"
Status = 'Gathering images'
CurrentOperation = ''
PercentComplete = 0
Id = 1
ParentId = -1
}
Write-Progress @progressBar
##get images
$imageFolder = 'S:NSC914INS Vendor Data ProjectEcommerce FTP Images' + $vendorName + 'Images Consolidated'
$images = Get-ChildItem -Path $imageFolder
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##get vendor's excel file
$excelFolder = 'S:SharedProduct Enrichment DataEmergency Image Sprint'
$vendorFile = Get-ChildItem -Path $excelFolder | Where-Object {$_.Name -like $vendorName + '*'} | Select-Object -ExpandProperty FullName
##start excel and open vendor file
$progressBar.Status = 'Working with Excel'; $progressBar.CurrentOperation = 'Opening Excel'; $progressBar.PercentComplete = 0; Write-Progress @progressBar
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Open($vendorFile)
$worksheet = $workbook.Worksheets.Item($sheetName)
$excel.Visible = $true
$rowCount = $worksheet.UsedRange.Rows.Count
$progressBar.PercentComplete = 50; Write-Progress @progressBar
$hyperlinkchunk1 = "=HYPERLINK("""
$hyperlinkchunk2 = """, """
$hyperlinkchunk3 = """)"
##stores column number based on user's input of column letter
$x = $worksheet.Range("${abcColorColumn}1").Column
$y = $worksheet.Range("${colorSwatchImageHyperlinkColumn}1").Column
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##check if color matches any of the image file names
##if a match is found, creates a hyperlink to that image in the Colorswatchimagehyperlink column
for ($i=2; $i -le $rowCount; $i++) {
$progressBar.CurrentOperation = "Checking line $i of $rowCount"; $progressBar.PercentComplete = ($i / $rowCount) * 100; Write-Progress @progressBar
$color = $worksheet.Cells.Item($i,$x).Text -replace 's','' ##Item() = (row,column)
foreach ($image in $images) {
if (($image.BaseName -replace 'W','') -match $color) { ##needs to be longerString -match shorterString
$worksheet.Cells.Item($i,$y).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
$worksheet.Cells.Item($i,$y).Font.Underline = $false
$worksheet.Cells.Item($i,$y).Font.ColorIndex = $xlAutomatic
}
}
}
##format, save, and quit excel; release comObjects
$progressBar.CurrentOperation = 'Saving and closing'; $progressBar.PercentComplete = 50; Write-Progress @progressBar
$worksheet.Columns($colorSwatchImageHyperlinkColumn).AutoFit()
$workbook.SaveAs($excelFolder+$saveAsName)
$workbook.Close()
$excel.Quit()
Get-Process excel | Stop-Process -Force
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheet)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
excel powershell
New contributor
$endgroup$
add a comment |
$begingroup$
I'm rather new to PowerShell so I could use some help with why my script is running so slow. It starts off just fine, and even the first 30 or so iterations of the for loop are zippy. But by the time my for
loop gets to around 75 iterations, it has slowed down to ~20 seconds per iteration. Do I need to do some garbage collection? Any insight is much appreciated!
Since you obviously don't have the files I'm working with, here are some details:
- my excel file is 342 lines
- my image folder contains 50 images
- an example of the matching I'm doing would be color: WEATHERED BLEND image: NovikShake_HS_WeatheredBlend.jpg
######################################################################################################################
# manually enter these values:
$vendorName = 'CompanyX'
$saveAsName = "CompanyX Items $(get-date -f yyyy-MM-dd).xlsx"
$sheetName = 'Items'
$colorColumn = 'G'
$colorSwatchImageHyperlinkColumn = 'Y'
######################################################################################################################
#progress bar function
$progressBar = @{
Activity = "Processing $vendorName file"
Status = 'Gathering images'
CurrentOperation = ''
PercentComplete = 0
Id = 1
ParentId = -1
}
Write-Progress @progressBar
##get images
$imageFolder = 'S:NSC914INS Vendor Data ProjectEcommerce FTP Images' + $vendorName + 'Images Consolidated'
$images = Get-ChildItem -Path $imageFolder
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##get vendor's excel file
$excelFolder = 'S:SharedProduct Enrichment DataEmergency Image Sprint'
$vendorFile = Get-ChildItem -Path $excelFolder | Where-Object {$_.Name -like $vendorName + '*'} | Select-Object -ExpandProperty FullName
##start excel and open vendor file
$progressBar.Status = 'Working with Excel'; $progressBar.CurrentOperation = 'Opening Excel'; $progressBar.PercentComplete = 0; Write-Progress @progressBar
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Open($vendorFile)
$worksheet = $workbook.Worksheets.Item($sheetName)
$excel.Visible = $true
$rowCount = $worksheet.UsedRange.Rows.Count
$progressBar.PercentComplete = 50; Write-Progress @progressBar
$hyperlinkchunk1 = "=HYPERLINK("""
$hyperlinkchunk2 = """, """
$hyperlinkchunk3 = """)"
##stores column number based on user's input of column letter
$x = $worksheet.Range("${abcColorColumn}1").Column
$y = $worksheet.Range("${colorSwatchImageHyperlinkColumn}1").Column
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##check if color matches any of the image file names
##if a match is found, creates a hyperlink to that image in the Colorswatchimagehyperlink column
for ($i=2; $i -le $rowCount; $i++) {
$progressBar.CurrentOperation = "Checking line $i of $rowCount"; $progressBar.PercentComplete = ($i / $rowCount) * 100; Write-Progress @progressBar
$color = $worksheet.Cells.Item($i,$x).Text -replace 's','' ##Item() = (row,column)
foreach ($image in $images) {
if (($image.BaseName -replace 'W','') -match $color) { ##needs to be longerString -match shorterString
$worksheet.Cells.Item($i,$y).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
$worksheet.Cells.Item($i,$y).Font.Underline = $false
$worksheet.Cells.Item($i,$y).Font.ColorIndex = $xlAutomatic
}
}
}
##format, save, and quit excel; release comObjects
$progressBar.CurrentOperation = 'Saving and closing'; $progressBar.PercentComplete = 50; Write-Progress @progressBar
$worksheet.Columns($colorSwatchImageHyperlinkColumn).AutoFit()
$workbook.SaveAs($excelFolder+$saveAsName)
$workbook.Close()
$excel.Quit()
Get-Process excel | Stop-Process -Force
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheet)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
excel powershell
New contributor
$endgroup$
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago
add a comment |
$begingroup$
I'm rather new to PowerShell so I could use some help with why my script is running so slow. It starts off just fine, and even the first 30 or so iterations of the for loop are zippy. But by the time my for
loop gets to around 75 iterations, it has slowed down to ~20 seconds per iteration. Do I need to do some garbage collection? Any insight is much appreciated!
Since you obviously don't have the files I'm working with, here are some details:
- my excel file is 342 lines
- my image folder contains 50 images
- an example of the matching I'm doing would be color: WEATHERED BLEND image: NovikShake_HS_WeatheredBlend.jpg
######################################################################################################################
# manually enter these values:
$vendorName = 'CompanyX'
$saveAsName = "CompanyX Items $(get-date -f yyyy-MM-dd).xlsx"
$sheetName = 'Items'
$colorColumn = 'G'
$colorSwatchImageHyperlinkColumn = 'Y'
######################################################################################################################
#progress bar function
$progressBar = @{
Activity = "Processing $vendorName file"
Status = 'Gathering images'
CurrentOperation = ''
PercentComplete = 0
Id = 1
ParentId = -1
}
Write-Progress @progressBar
##get images
$imageFolder = 'S:NSC914INS Vendor Data ProjectEcommerce FTP Images' + $vendorName + 'Images Consolidated'
$images = Get-ChildItem -Path $imageFolder
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##get vendor's excel file
$excelFolder = 'S:SharedProduct Enrichment DataEmergency Image Sprint'
$vendorFile = Get-ChildItem -Path $excelFolder | Where-Object {$_.Name -like $vendorName + '*'} | Select-Object -ExpandProperty FullName
##start excel and open vendor file
$progressBar.Status = 'Working with Excel'; $progressBar.CurrentOperation = 'Opening Excel'; $progressBar.PercentComplete = 0; Write-Progress @progressBar
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Open($vendorFile)
$worksheet = $workbook.Worksheets.Item($sheetName)
$excel.Visible = $true
$rowCount = $worksheet.UsedRange.Rows.Count
$progressBar.PercentComplete = 50; Write-Progress @progressBar
$hyperlinkchunk1 = "=HYPERLINK("""
$hyperlinkchunk2 = """, """
$hyperlinkchunk3 = """)"
##stores column number based on user's input of column letter
$x = $worksheet.Range("${abcColorColumn}1").Column
$y = $worksheet.Range("${colorSwatchImageHyperlinkColumn}1").Column
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##check if color matches any of the image file names
##if a match is found, creates a hyperlink to that image in the Colorswatchimagehyperlink column
for ($i=2; $i -le $rowCount; $i++) {
$progressBar.CurrentOperation = "Checking line $i of $rowCount"; $progressBar.PercentComplete = ($i / $rowCount) * 100; Write-Progress @progressBar
$color = $worksheet.Cells.Item($i,$x).Text -replace 's','' ##Item() = (row,column)
foreach ($image in $images) {
if (($image.BaseName -replace 'W','') -match $color) { ##needs to be longerString -match shorterString
$worksheet.Cells.Item($i,$y).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
$worksheet.Cells.Item($i,$y).Font.Underline = $false
$worksheet.Cells.Item($i,$y).Font.ColorIndex = $xlAutomatic
}
}
}
##format, save, and quit excel; release comObjects
$progressBar.CurrentOperation = 'Saving and closing'; $progressBar.PercentComplete = 50; Write-Progress @progressBar
$worksheet.Columns($colorSwatchImageHyperlinkColumn).AutoFit()
$workbook.SaveAs($excelFolder+$saveAsName)
$workbook.Close()
$excel.Quit()
Get-Process excel | Stop-Process -Force
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheet)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
excel powershell
New contributor
$endgroup$
I'm rather new to PowerShell so I could use some help with why my script is running so slow. It starts off just fine, and even the first 30 or so iterations of the for loop are zippy. But by the time my for
loop gets to around 75 iterations, it has slowed down to ~20 seconds per iteration. Do I need to do some garbage collection? Any insight is much appreciated!
Since you obviously don't have the files I'm working with, here are some details:
- my excel file is 342 lines
- my image folder contains 50 images
- an example of the matching I'm doing would be color: WEATHERED BLEND image: NovikShake_HS_WeatheredBlend.jpg
######################################################################################################################
# manually enter these values:
$vendorName = 'CompanyX'
$saveAsName = "CompanyX Items $(get-date -f yyyy-MM-dd).xlsx"
$sheetName = 'Items'
$colorColumn = 'G'
$colorSwatchImageHyperlinkColumn = 'Y'
######################################################################################################################
#progress bar function
$progressBar = @{
Activity = "Processing $vendorName file"
Status = 'Gathering images'
CurrentOperation = ''
PercentComplete = 0
Id = 1
ParentId = -1
}
Write-Progress @progressBar
##get images
$imageFolder = 'S:NSC914INS Vendor Data ProjectEcommerce FTP Images' + $vendorName + 'Images Consolidated'
$images = Get-ChildItem -Path $imageFolder
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##get vendor's excel file
$excelFolder = 'S:SharedProduct Enrichment DataEmergency Image Sprint'
$vendorFile = Get-ChildItem -Path $excelFolder | Where-Object {$_.Name -like $vendorName + '*'} | Select-Object -ExpandProperty FullName
##start excel and open vendor file
$progressBar.Status = 'Working with Excel'; $progressBar.CurrentOperation = 'Opening Excel'; $progressBar.PercentComplete = 0; Write-Progress @progressBar
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Open($vendorFile)
$worksheet = $workbook.Worksheets.Item($sheetName)
$excel.Visible = $true
$rowCount = $worksheet.UsedRange.Rows.Count
$progressBar.PercentComplete = 50; Write-Progress @progressBar
$hyperlinkchunk1 = "=HYPERLINK("""
$hyperlinkchunk2 = """, """
$hyperlinkchunk3 = """)"
##stores column number based on user's input of column letter
$x = $worksheet.Range("${abcColorColumn}1").Column
$y = $worksheet.Range("${colorSwatchImageHyperlinkColumn}1").Column
$progressBar.PercentComplete = 100; Write-Progress @progressBar
##check if color matches any of the image file names
##if a match is found, creates a hyperlink to that image in the Colorswatchimagehyperlink column
for ($i=2; $i -le $rowCount; $i++) {
$progressBar.CurrentOperation = "Checking line $i of $rowCount"; $progressBar.PercentComplete = ($i / $rowCount) * 100; Write-Progress @progressBar
$color = $worksheet.Cells.Item($i,$x).Text -replace 's','' ##Item() = (row,column)
foreach ($image in $images) {
if (($image.BaseName -replace 'W','') -match $color) { ##needs to be longerString -match shorterString
$worksheet.Cells.Item($i,$y).Value = $hyperlinkchunk1 + $image.FullName + $hyperlinkchunk2 + $image.Name + $hyperlinkchunk3
$worksheet.Cells.Item($i,$y).Font.Underline = $false
$worksheet.Cells.Item($i,$y).Font.ColorIndex = $xlAutomatic
}
}
}
##format, save, and quit excel; release comObjects
$progressBar.CurrentOperation = 'Saving and closing'; $progressBar.PercentComplete = 50; Write-Progress @progressBar
$worksheet.Columns($colorSwatchImageHyperlinkColumn).AutoFit()
$workbook.SaveAs($excelFolder+$saveAsName)
$workbook.Close()
$excel.Quit()
Get-Process excel | Stop-Process -Force
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheet)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
excel powershell
excel powershell
New contributor
New contributor
edited 7 hours ago
Sᴀᴍ Onᴇᴌᴀ
9,27262161
9,27262161
New contributor
asked 8 hours ago
JfireJfire
1
1
New contributor
New contributor
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago
add a comment |
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Jfire is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212030%2fpowershell-script-slows-down-during-for-loop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Jfire is a new contributor. Be nice, and check out our Code of Conduct.
Jfire is a new contributor. Be nice, and check out our Code of Conduct.
Jfire is a new contributor. Be nice, and check out our Code of Conduct.
Jfire is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212030%2fpowershell-script-slows-down-during-for-loop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal♦
1 hour ago