Forum Discussion

vivek10688's avatar
vivek10688
Copper Contributor
Jul 26, 2022

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

  • farismalaeb's avatar
    farismalaeb
    Steel Contributor

    You can use VSCode, Select the text you want, and from Edit Menu, select Toggle Comment Block.

     

    • vivek10688's avatar
      vivek10688
      Copper Contributor
      Hi ,

      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.
      • farismalaeb's avatar
        farismalaeb
        Steel Contributor
        Another question, You have 3 If block, how the script knows which block should be commented?
  • LainRobertson's avatar
    LainRobertson
    Silver Contributor

    vivek10688 

     

    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

    • vivek10688's avatar
      vivek10688
      Copper Contributor
      Hi 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
      • LainRobertson's avatar
        LainRobertson
        Silver Contributor

        vivek10688 

         

        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

Resources