Forum Discussion
Comment Or Un-Comment Multiple Lines In PowerShell Script
Problem Statement: I have a PowerShell script and before executing it I want to comment multiple lines using PowerShell command
Series Of Steps Need To Performed
1. Comment multiple lines in PowerShell script.
2. Execute the script.
3. Un-Comment commented or multiple lines in PowerShell script.
Purpose:
PowerShell scripts is having multiple steps to execute and I want to execute certain steps as per use cases by commenting & uncommenting the block of code.
For Example: In-below PowerShell script I want to comment out second "if " block where string should match as "$RestartNumber -le 1" and get it's line number and put "<#" before if statement and put "#>" after the end of "if statement" curly braces "}".
In notepad or any other editor , you can simply manually just put "<#" & "#>" before & after line to make whole if statement block commented & uncommented. Wondering How we can do it through powershell.
If ($RestartNumber -eq 0)
{
$RestartNumber = Read-Host -Prompt 'Input number to restart the script at or <return> to start at the beginning: '
}
If ($RestartNumber -le 1)
{
ExecuteOrSkipPause
If ($Script:Continue)
{
foreach ($a in $b)
{
foreach ($c in $d)
{
Try
{
}
Catch
{
}
}
}
}
}
If ($RestartNumber -le 2)
{
ExecuteOrSkipPause
If ($Script:Continue)
{
foreach ($e in $f)
{
foreach ($g in $h)
{
Try
{
}
Catch
{
}
}
}
}
}
If ($RestartNumber -le 3)
{
ExecuteOrSkipPause
If ($Script:Continue)
{
foreach ($i in $j)
{
foreach ($k in $l)
{
Try
{
}
Catch
{
}
}
}
}
}
Thanks
Vivek
- farismalaebSteel Contributor
You can use VSCode, Select the text you want, and from Edit Menu, select Toggle Comment Block.
- vivek10688Copper ContributorHi ,
Thanks for answering. However, that is not the use case, I want to do the same thing but through power shell script like using Get-content and loop over through lines and dynamically find out if block start & it's end and then commented out.- farismalaebSteel ContributorAnother question, You have 3 If block, how the script knows which block should be commented?
- LainRobertsonSilver Contributor
This is almost an open-ended question since it raises more questions than we can easily answer in short-form.
I'll start with a dangerously-simple statement: yes, it's possible to comment different sections, however, it would not be trivial to do so as there are many unintended consequences that could come from this.
My question though is, what are you really trying to achieve here? Are you really just looking for a way to run specific blocks - which is what your "if ($RestartNumber -le x)" suggests, or are the comments serving another purpose?
There's a number of ways you could approach this but I think your idea of using "if ($RestartNumber)" is probably good enough.
Option 1: A big, fat "while" loop
Nothing complex about this one.
Basically, you're simply putting your entire existing code block from your original post inside of a "where" loop, which makes use of a Read-Host prompt to retrieve whatever user input you need.
I'd go with a basic variation like the one below - purely in the interests of offering a little more control over exactly what executes, given using operators like "less than" or "greater than" implicitly mean you'll be running or skipping entire chains.
Example code
while (($UserInput = Read-Host -Prompt "Enter the code block numbers to execute - separated by commas, or enter Q to quit") -ne "q") { if ([string]::IsNullOrWhiteSpace($UserInput)) { # If nothing was input, go back to the start and re-prompt. continue; } # Remove any unexpected padding, etc. before breaking it up into an array for ease of reference in the subsequent "if" blocks. $Sections = [regex]::Replace($UserInput, "[^0-9,]", "", [System.Text.RegularExpressions.RegexOptions]::CultureInvariant).Split(","); # Code block 1 if ($Sections.Contains("1")) { Write-Host "Hello from code block 1."; } # Code block 2 if ($Sections.Contains("2")) { Write-Host "Hello from code block 2."; } }
Example output from example code
Again, this is just a really basic hypothetical approach since I'm not 100 per cent clear on what you're really trying to achieve, and whether the comments are a "must have" or just a means to an end.
Option 2: Use metadata to control segmentation
Alternatively, you could go down the path of using metadata within the script to act as parsing indicators. You'd then read and parse the same file, choosing to execute (or comment, if there's some reason you must have this taking place) as you go.
This is a complex path, which I'm absolutely not going to codify as there's just too many "what ifs" to contend with, but the following should serve as an abstract example.
Here, we've:
- Put the code blocks into functions so that they don't auto-execute;
- Used the natively-supported "#region...#endregion" statements to also demarcate what constitutes a "code block" (i.e. the parsing routine would be looking for the number in the #region "tag";
- Once the parsing is done, you'll have some form of text stream (sting or similar), which you wold pass to something like either Invoke-Expression or dot-source the code block (both shown in the example below.)
#region Block 1 function CodeBlock1 { Write-Host "Hello from code block 1."; } #endregion #region Block 2 function CodeBlock2 { Write-Host "Hello from code block 2."; } #endregion # Now, write a bunch of code that reads and parses the file, saving it as a text stream. # After that, use something like: Invoke-Expression -Command $ParsedText; # or (if you like doing things the hard way): $Code = [scriptblock]::Create($ParsedText); . $Code;
(Note: This code will not work - it's only demonstrating an abstract framework for the bullet points above)
There's probably other options but this is like going down the rabbit hole, so I'm going to stop here.
Cheers,
Lain
- vivek10688Copper ContributorHi Lain,
Thanks for writing the answer.
Objective :
Let say you have the content of powershell script in variable called $filecontent and then you do iteration in foreach loop where you do match string like 'RestartNumber -le 1' of if block and then gets line number and insert '<#' before the linenumber and eventually using same logic to get the line number of end of the if block and insert '#>' after the linenumber. This way the second if block will be commented out and will not be executed during execution of powershell script The purpose is simple comment the if block which you do not want to get it execute but not manually instead through powershell script.
Thanks
Vivek- LainRobertsonSilver Contributor
Yes, you can do it that way.
That's the basically the same as the second option I mentioned, just using a different (and harder to identify, in the case of the closing curly brace) set of "markers".
Both approaches will allow you to control which blocks you do/don't run.
Cheers,
Lain