Can I use variables in the PowerShell Replace method? - powershell

My goal is to run a PowerShell command that will update the text in a markdown table.
My project structure looks like:
/root  
dashboardTable.md  
replace.ps1
dashboardTable.md:
App Name | Build Version | QA Version | Prod Version
------ | ------ | ------ | ------ |
ProjectName |0.0.0 | 0.0.0 | 0.0.0
replace.ps1
(Get-Content ./dashboardTable.md).replace('0.0.0', '0.0.1') | Set-Content './dashboardTable.md'
Running this command works and will change the markdown file to:
App Name | Build Version | QA Version | Prod Version
------ | ------ | ------ | ------ |
ProjectName |0.0.1 | 0.0.1 | 0.0.1
I am trying to set a variable that can be used in place of the hardcoded values in the replace method, for example:
$MyVariable = '0.0.0'
(Get-Content ./dashboardTable.md).replace($MyVariable, '0.0.1') | Set-Content './dashboardTable.md'
But this changes my markdown file to:
App Name | Build Version | QA Version | Prod Version
------ | ------ | ------ | ------ |
0.0.1 |0.0.0 | 0.0.0 | 0.0.0
I even tried to switch the replace values around and run the PowerShell command like:
$MyVariable = '0.0.1'
(Get-Content ./dashboardTable.md).replace('0.0.0', $MyVariable) | Set-Content './dashboardTable.md'
And it changes the markdown to:
App Name | Build Version | QA Version | Prod Version
------ | ------ | ------ | ------ |
ProjectName |ProjectName | ProjectName | ProjectName
Is it possible to use a variable like this?

I'm not sure why I was getting the results I was getting however, I do know there was an issue when I was calling the PowerShell script.
To fix the issue, when I want to run the script, I run this command in the PowerShell Integrated Terminal:
powershell -executionpolicy bypass ".\replace.ps1" and was able to get the expected results.

Related

How to transcript everything in console

Hey i'm trying to get the device code that's being printed to the console in powershell when running "Connect-ExchangeOnline -Device". However it doesn't get appended to the output file along with everything else when I use start transcribe.
Start-Transcript -path "Path" -append
$DebugPreference = 'Continue'
$VerbosePreference = 'Continue'
$InformationPreference = 'Continue'
Connect-ExchangeOnline -Device -Verbose
Expected output:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code CDWS27A56 to authenticate.
Actual output:
The module allows access to all existing remote PowerShell (V1) cmdlets in addition to the 9 new, faster, and more reliable cmdlets.
|--------------------------------------------------------------------------|
| Old Cmdlets | New/Reliable/Faster Cmdlets |
|--------------------------------------------------------------------------|
| Get-CASMailbox | Get-EXOCASMailbox |
| Get-Mailbox | Get-EXOMailbox |
| Get-MailboxFolderPermission | Get-EXOMailboxFolderPermission |
| Get-MailboxFolderStatistics | Get-EXOMailboxFolderStatistics |
| Get-MailboxPermission | Get-EXOMailboxPermission |
| Get-MailboxStatistics | Get-EXOMailboxStatistics |
| Get-MobileDeviceStatistics | Get-EXOMobileDeviceStatistics |
| Get-Recipient | Get-EXORecipient |
| Get-RecipientPermission | Get-EXORecipientPermission |
|--------------------------------------------------------------------------|
To get additional information, run: Get-Help Connect-ExchangeOnline or check https://aka.ms/exops-docs
Send your product improvement suggestions and feedback to exocmdletpreview#service.microsoft.com. For issues related to the module, contact Microsoft support. Don't use the feedback alias for problems or support issues.
----------------------------------------------------------------------------

Switching Azure AD Tenants in Azure DevOps

Is it possible to manually map all users when switching the Azure Active Directory connection for Azure DevOps?
The directory that we're switching to has guest accounts for the source UPN set up for 95% of the users in ADO, so they're automatically mapped. Rather than that happening, we'd like to map each source user to their new UPN in the destination domain.
What's happening
| Source UPN | Source Type | | Destination UPN | Destination Type |
| ---------- | ----------- | ---- | --------------- | ---------------- |
| user#a.com | Member | \ | user#b.com | Member |
| | | -> | user#a.com | Guest |
What we want to happen
| Source UPN | Source Type | | Destination UPN | Destination Type |
| ---------- | ----------- | ---- | --------------- | ---------------- |
| user#a.com | Member | ---> | user#b.com | Member |
| | | | user#a.com | Guest |
Is it possible to manually map all users when switching the Azure Active Directory connection for Azure DevOps?
I am afraid there is no such way to manually map all users when switching the AAD connection for Azure DevOps. Automatically map behavior is by designed, in order to provide us with convenience when switching AAD.
If we want to manually map the users, we need to delete those users from target AAD before switching AAD. In this case, when we switch AAD, Azure Devops says "X member(s) of the xxx organization can't sign in because they're not in the XX AAD. Delete any unwanted users in Organization settings, and then Resolve for remaining members.". Hit the resolve button a page shows up with the Users, then we can match them manually.

Disable all the unwanted Windows Firewall rules using PowerShell

In my Windows Firewall, I've created certain rules that give me more control over my PC. But my rules have become somewhat useless since Windows and other apps are kept adding rules that I don't want.
I've tried to prevent this from happening, but the only way I've found is to use a third-party tool like Tinywall, which isn't exactly what I'm looking for.
So, to fix this, I want to create a PowerShell script that will disable and rename all rules that are not added by me. This way, I can manage them easily.
Rules that are added by me can be easily recognized because all of them start with certain words.
In this case, let's assume it starts with either 'Sample XYZ' or 'Sample ABC'.
Sample XYZ - Windows Update
Sample ABC - MPC-HC
Sample ABC - Firefox
Sample XYZ - Windows News
So far, this is what I have done.
In this part, the script will filter all the rules that I have created and then it'll disable & block all other rules.
To my surprise, this is working as expected.
# This will get all firewall rules
$NR = Get-NetFirewallRule
# This will exclude all the rules added by the user
$NR = $NR | Where-Object DisplayName -NotMatch "Sample ABC"
$NR = $NR | Where-Object DisplayName -NotMatch "Sample XYZ"
# Disable all other rules that are not added by the user
$NR | Set-NetFirewallRule -Enabled False
# Set rules' action to block
$NR | Set-NetFirewallRule -Action Block
These are the parts that don't work.
Task: Add a custom word to the beginning of the rules' display name
Example: If a rule name is 'Microsoft Photos', then it'll be renamed to 'IDWTFR - Microsoft Photos'.
# Add a custom word to the beginning of the rules' display name
# Custom word = 'IDWTFR - '
# Attempt 01: Fail
$NR | Set-NetFirewallRule -DisplayName "IDWTFR - " + $NR.DisplayName
# Attempt 02: Fail
$NR = $NR | ForEach-Object -MemberName DisplayName "IDWTFR - " + $NR.DisplayName | Set-NetFirewallRule
Task: Add unwanted rules to a group named 'Junk Rules'.
# Add to a group
# Attempt 01: Fail
$NR | Set-NetFirewallRule -DisplayGroup "Junk Rules"
To clarify it a bit more, this is the summary of what I am trying to do.
+-----------------------------+---------------------------+----------------+----------------+----------------+-------------+
| Rule Name | New Rule Name | Group | Action | Status | Created by |
+-----------------------------+---------------------------+----------------+----------------+----------------+-------------+
| Sample XYZ - Windows Update | Same as before | Same as before | Same as before | Same as before | User |
| Sample ABC - MPC-HC | Same as before | Same as before | Same as before | Same as before | User |
| Sample ABC - Firefox | Same as before | Same as before | Same as before | Same as before | User |
| Sample XYZ - Windows News | Same as before | Same as before | Same as before | Same as before | User |
| Microsoft Photos | IDWTFR - Microsoft Photos | Junk Rules | Block | Disable | Not by user |
| App Installer | IDWTFR - App Installer | Junk Rules | Block | Disable | Not by user |
| Feedback Hub | IDWTFR - Feedback Hub | Junk Rules | Block | Disable | Not by user |
| Microsoft Edge | IDWTFR - Microsoft Edge | Junk Rules | Block | Disable | Not by user |
+-----------------------------+---------------------------+----------------+----------------+----------------+-------------+
I'm new to PowerShell, so any help will be appreciated. Thanks.
Since this is your special use case, it's going to a challenge for one to validate without setting up an environment as close as possible to what you show here. I am in no position to do that.
Yet, looking at what you say you have done, here is a refactor option to try. Refactor a bit (again, not tested)
# Get all firewall rule name, and filter out the named rules
Get-NetFirewallRule |
Where-Object -Property Name -notlike 'Sample ABC|Sample XYZ' |
ForEach {
# Disable all other rules that are not added by the user
Set-NetFirewallRule -Name $PSItem.DisplayGroup -Enabled False
# Set rules' action to block
$PSItem.DisplayName |
Set-NetFirewallRule -Action Block
# Rename firewall rule
If ($PSItem.DisplayName -like '*Microsoft*')
{Rename-NetFirewallRule -Name $PSItem.DisplayName -NewName "IDWTFR-$($PSitem.DisplayName)"}
# Create new firewall group
$PSItem.Group = 'JunkRules' |
Set-NetFirewallRule -NewDisplayName $PSItem.DisplayName
}

What is the conventional structure of a modular Java 9 (Eclipse) project?

As an example, say I have a program named Abc containing one class named Xyz. The code is located in a Git repository containing a single Eclipse project. I've adopted the Maven source directory layout. Before Java 9 the project structure might have looked like this (simplified):
Abc.git
|
+---.git
|
+---Abc
|
+---.settings
|
+---.project
|
+---.classpath
|
+---src
|
+---main
| |
| +---java (source folder)
| |
| +---com
| |
| +---abc
| |
| +---Xyz.java
+---test
|
+---java (source folder)
|
+---com
|
+---abc
|
+---XyzTest.java
The JUnit tests were typically in the same packages as the production code, but in a different source folder. But now the production code is in a module. A package being tested can't be split into separate modules. Furthermore, some classes under test may reside in packages not exported by their module.
What is the correct practice in terms of code organization to address these issues?
This question is not about Maven. What I meant was: Is this the recommended way to do it?
Abc.git
|
+---.git
|
+---Abc
|
+---.settings
|
+---.project
|
+---.classpath
|
+---src
|
+---main
| |
| +---java
| |
| +---com.abc (source folder?)
| |
| +---module-info.java (exports com.abc)
| |
| +---com
| |
| +---abc
| |
| +---Xyz.java
+---test
|
+---java
|
What goes here?

Using Select-Object on two adjacent lines in a row outputs a "broken" list

Consider the following example:
if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") -eq $null) {return}
$server = New-Object Microsoft.SqlServer.Management.Smo.Server servername
$server | Select Name, Product, Edition, VersionString
$server.Databases | select name,CompatibilityLevel
If executed line per line on the command line, the output will somewhat resemble the following:
Name Product Edition VersionString
---- ------- ------- -------------
SERVERNAME Microsoft SQL Server Developer Edition (64-bit) 12.0.4213.0
Name CompatibilityLevel
---- ------------------
Database123456789 Version100
Database234567890 Version100
If executed as a script, the output looks like the following (note the missing "Version100"...):
Name Product Edition VersionString
---- ------- ------- -------------
SERVERNAME Microsoft SQL Server Developer Edition (64-bit) 12.0.4213.0
Database123456789
Database234567890
Even changing the script like this won't help with the output being messed up.
if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") -eq $null) {return}
$server = New-Object Microsoft.SqlServer.Management.Smo.Server servername
$server | Select Name, Product, Edition, VersionString
Write-Host "Databases on $($server.Name):"
$server.Databases | select name,CompatibilityLevel
Instead the output will look like this:
Name Product Edition VersionString
---- ------- ------- -------------
SERVERNAME Microsoft SQL Server Developer Edition (64-bit) 12.0.4213.0
Databases on SERVERNAME:
Database123456789
Database234567890
How can I force PowerShell to output the CompatibilityLevel member?
You could use the Format-Table cmdlet to force the output:
$server.Databases | select name,CompatibilityLevel | Format-Table