Link to home
Start Free TrialLog in
Avatar of janhoedt
janhoedt

asked on

Regex & powershell, replace values between "" (only between #################### in a file)?

Hi,

I have a ps1 in which I would like to replace all values for variables between ####################
So that would be: Variables.ps1
 ####################
$RDSServer = "server01"
$ExchangeServer = "server02"
etc
 ####################

How can I remove the values?
I could get the content via get-content c:\globalvariables
But  how then the regex to get the data between  ####################
and then replace the value between " " ?
J.
Avatar of footech
footech
Flag of United States of America image

Essentially you have to search for the text that demarks an editable region.  Before that, you emit the line unchanged.  The first time you encounter it, a flag gets flipped so that you know you should perform the remove operations.  And when you encounter it a second time, the flag gets flipped again, so that lines are emitted unchanged again.
Get-Content file.txt | ForEach -Begin { $editable = $false } -Process `
{
    If ( $_ -match "^\s*#+\s*$" )
    {
        # we have entered/exited editable region
        # change the editable state
        $editable = -not $editable
        $_
    }
    ElseIf ( -not $editable )
    { $_ }
    ElseIf ( $editable )
    {
        $_ -replace '(\s*\$.+=\s*("|'')).+(("|'').*)', '$1$2'
    }
} | Set-Content newfile.txt

Open in new window

Are you changing your own (executing) PS script?
Avatar of janhoedt
janhoedt

ASKER

And what should the script do? Don't see anything happening in the newfile.txt
For a file with the content in your example
####################
$RDSServer = "server01"
$ExchangeServer = "server02"
etc
 ####################

...it results in a file with the following:
####################
$RDSServer = ""
$ExchangeServer = ""
etc
 ####################


If that's not what you want, provide two sample files.
1) with sample input
2) with what you expect the output to be
Thanks, will check again Note: I m using $gloval:server01 but probably it does not matter?
meant global of course
@janhoedt - Please followup to confirm that the script is doing what you want (or not).
Hi, thanks for the update.
Created a sample input, below, the output just should be a file with all variables between the ##### set tot ""

function get-test123{}

####################
#GENERAL
$Global:Company = "OurCompany"
$Global:Organization = "OurOrganization"
$Global:EmailSuffix = "@OurCompany.com"
$Global:DomainFQDN = $env:USERDNSDOMAIN
$Global:SCCMSiteCode01 = "SLT"
$Global:MailFromAddress = "noreply$EmailSuffix"
$Global:MailToAddressforAlerts = "mymailaddress$EmailSuffix"
#SERVERS
$Global:SCCMSiteServer01 = 'serversccm01'
$Global:PublicSMTPServer01 = 'SMTP' #SMTP server which does not need authentication
$Global:ConnectionBroker01 = 'server01'
#RDS
$Global:CollectionRemoteapps = 'CollectionRemoteapps01'
#SOFTWARE GENERAL
$Global:PackageSourcesShare = "\\$DomainFQDN\PackageSources\"
#SOFTWARE PER TECHNOLOGY
$Global:AppVPackagesShare = "\\$DomainFQDN\AppV"
#SCCM VARIABLES FOR deployments/queries
$Global:CMDeployPurpose = 'Required' #Available or Required
$Global:CMDeployLogFile = Join-Path  $PackageSourcesShare -childpath 'Deployments.log'
$Global:CMDistributionPointGroupName = "$Company DG"
$Global:RDSADGroupNames = @{ 
  Group01 = 'APPLICATION01'
  Group02 = 'APPLICATION02'
}
####################

#OtherStuff like
#FQDN
$Global:SCCMSiteServer01_FQDN =  ($SCCMSiteServer01 + "." + $DomainFQDN)
$Global:PublicSMTPServer01_FQDN = ($PublicSMTPServer01 + "." + $DomainFQDN)

Open in new window

Please provide an example where you have a similar (name = delimitedvalue) pattern outside of the ############ lines.  Your example can easily be changed with a simple replace, not involving any iteration or logic.
Sorry, don't get your question. The example I posted is exactly what I need.
$a = Get-Content "C:\Users\Mark\Downloads\Q_29088564.txt"
$a -match "((?:.|\n)+?##+)((?:.|\n)+?)(##+(?:.|\n)+)" > null
$matches[2] = ($matches[2] -replace ' = +([''"])([^\1]*?)\1', ' = $1$1')
$matches[1..($matches.count)] -join ''

Open in new window

Produces the following:
function get-test123{}

####################
#GENERAL
$Global:Company = ""
$Global:Organization = ""
$Global:EmailSuffix = ""
$Global:DomainFQDN = $env:USERDNSDOMAIN
$Global:SCCMSiteCode01 = ""
$Global:MailFromAddress = ""
$Global:MailToAddressforAlerts = ""
#SERVERS
$Global:SCCMSiteServer01 = ''
$Global:PublicSMTPServer01 = '' #SMTP server which does not need authentication
$Global:ConnectionBroker01 = ''
#RDS
$Global:CollectionRemoteapps = ''
#SOFTWARE GENERAL
$Global:PackageSourcesShare = ""
#SOFTWARE PER TECHNOLOGY
$Global:AppVPackagesShare = ""
#SCCM VARIABLES FOR deployments/queries
$Global:CMDeployPurpose = '' #Available or Required
$Global:CMDeployLogFile = Join-Path  $PackageSourcesShare -childpath 'Deployments.log'
$Global:CMDistributionPointGroupName = ""
$Global:RDSADGroupNames = @{ 
  Group01 = ''
  Group02 = ''
}
####################

#OtherStuff like
#FQDN
$Global:SCCMSiteServer01_FQDN =  ($SCCMSiteServer01 + "." + $DomainFQDN)
$Global:PublicSMTPServer01_FQDN = ($PublicSMTPServer01 + "." + $DomainFQDN)

Open in new window

Your requirement to limit the changes to the lines between the ############# lines is a bit of a red herring. If you don't actually have any possible changes outside those lines, the PS script can be simplified to this:
$a = Get-Content "C:\Users\Mark\Downloads\Q_29088564.txt"
$a -replace ' = +([''"])([^\1]*?)\1', ' = $1$1'

Open in new window


Or, all on one line:
(Get-Content "C:\Users\Mark\Downloads\Q_29088564.txt") -replace ' = +([''"])([^\1]*?)\1', ' = $1$1'

Open in new window

Great! Would you mind explaining what you are doing here?
Would love to understand it but don't :-)
ASKER CERTIFIED SOLUTION
Avatar of aikimark
aikimark
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks! I defintely have to dive into regex one day :-)

One more thing I would like to also "anonymize"  in the same textfile

$Global:ADGroupNames = @{
  $Group01 = 'technicians-ourcompany'
  $Group02 = 'marketing-ourcompany'
}
=> should become @{ Group01 = '' etc

I should then do a
$a -replace ..... what exactly?
Isn't that happening with my posted script?  I see GROUP01 = ''
No, didn't see that happening in my variables ....