Why -NotMatch is not working while using within a PowerShell script? - string

I have one XML file. I want to search for a string and then delete that line from the file.
Now the problem is that when I run following code from PS console, it works fine - deletes the line which contains "test3". But when I put the same code inside a PS script and run it, it is NOT deleting the intended line. Can you please let me know if I am missing something?
test.txt:
test1
test2
test3
test4
test5
test6
Code:
$loc = "D:\test.txt"
$msg = "test3"
$newF = Get-Content -Path $loc | where {$_ -notmatch $msg}
$newF
I am using PSVersion: 5.1.14393.1358.

Works absolutely fine. See the picture below.
Works fine from the console also.

-notmatch is designed to work with a regex. I'd suggest using -notlike in the future. As others have stated, your limited example is not reproducible.
Doc on -notmatch: Link

Related

how to get-content of text file on multiple servers using powershell

I'm trying to see if I can read a specific txt file (last x rows) on multiple servers.
I have tried this but its incorrect, can you please help me out?
Get-Content C:\Users\admin\server.txt | ForEach-Object {Get-Content "C:\project\file.log" | Select -Last 20}
The file is located on the same folder on each server.
The server.txt has all server names to which i have access with my current user, like
Server1
Server2
Server3
Thank you!
okay, guessing your server.txt file contains server names like \Server1 \Server2 with a line containing a single server name? What I see is wrong is this.
1) Change your ForEach to
Foreach-object($)
2) Inside your Foreach build the correct path. The $ var will be \Server1 so append \c$\Project\file.log
Not sure why the underscore is not showing up but the $ needs an underscore after it.
$server_names = Get-Content "C:\Users\hostlist.txt"
Foreach ($server in $server_names) {Get-Content "\$server\c$\test.log" | Select -Last 20}

PowerShell Split-Path does not work properly with IIS: drive qualifier

I am using PowerShell v3.0 and the IIS Administration Cmdlets to add and remove websites from my IIS 7 instance. I use Import-Module WebAdministration to make sure the IIS: drive is available, and I am able to use Remove-Item to delete files via the IIS: drive. For some reason though when I use the following code Split-Path always returns an empty string, even though the Remove-Item works fine.
$iisPath = Join-Path "IIS:\Sites" $fullPath
Remove-Item -Path $iisPath
$parent = Split-Path -Path $iisPath -Parent
Even if I comment out the Remove-Item line, Split-Path still returns an empty string. The $iisPath value would look something like this:
IIS:\Sites\Application Services\2.5.12\OurProductServicesDirectory
So I would expect $parent to contain:
IIS:\Sites\Application Services\2.5.12
But $parent is always empty. I have also tried creating the $iisPath using $iisPath = "IIS:\Sites\$fullPath", rather than Join-Path, but still get the same result.
Any ideas why Split-Path doesn't seem to work when using the IIS: drive, or how to fix it?
===UPDATE===
So I created a tiny sample script to see if I could reproduce the problem. Here it is:
$Block = {
Import-Module WebAdministration
$path = "IIS:\Sites\Application Services\2.5.12\OurProductServicesDirectory\"
Test-Path -Path $path
$parent = Split-Path -Path $path -Parent
Write-Host Parent is $parent
}
$Session = New-PSSession -ComputerName "Our.WebServer.local"
Invoke-Command -Session $Session -ScriptBlock $Block
Using this script $parent does get a value, but the text written to the console is:
True
Parent is IIS:Sites\Application Services
when I expect it to be:
True
Parent is IIS:\Sites\Application Services\2.5.12
So in my simple sample script I do get a value back, but it's the wrong value; it returns the grandparent directory instead of the parent directory, and it removes the backslash from after IIS:.
I'm not sure why I get different results in this sample script then in my main script, but both results appear to be wrong. Any suggestions are appreciated.
So because the IIS: qualifier is made valid by importing the WebAdministration module, I'm going to assume that Split-Path was simply never designed to work with the IIS: qualifier, and that is why it doesn't handle it properly.
The work around I found was simply to just exclude IIS:\Sites\ from my path when using Split-Path. So my original example would change to:
Remove-Item -Path "IIS:\Sites\$fullPath"
$parent = Split-Path -Path $fullPath -Parent
So basically I just leave IIS:\Sites\ off of all my paths, and then explicitly add it when needed, such as when calling Remove-Item, Test-Path, Get-ChildItems, etc. It's not the greatest solution, but it works.

Powershell excute node.js script and capture output

I have some strange situation in Powershell. When I run:
PS> node.exe [PATH_TO_GRUNT]\grunt
I got full output (30-40 lines), but when I run:
PS> Write-Host(node.exe [PATH_TO_GRUNT]\grunt)
I gives me only one line. What is wrong with this? I tried to add --no-color, 2>&1 options but they don't work at all.
Try with -Separator flag:
PS> Write-Host(node.exe [PATH_TO_GRUNT]\grunt) -Separator `n

Automatic deployment of solutions with PowerShell

I have a folder, containing several solutions for a SharePoint application, which I want to add and install. I want to iterate over the elements in the folder, then use the Add-SPSolution. After that I want to do a check if the solutions are done deploying, before using the Install-SPSolution. Here is a snippet that I am currently working on:
# Get the location of the folder you are currently in
$dir = $(gl)
# Create a list with the .wsp solutions
$list = Get-ChildItem $dir | where {$_.extension -eq ".wsp"}
Write-Host 'DEPLOYING SOLUTIONS...'
foreach($my_file in Get-ChildItem $list){Add-SPSolution -LiteralPath $my_file.FullName}
Write-Host 'SLEEP FOR 30 SECONDS'
Start-Sleep -s 30
Write-Host 'INSTALLING SOLUTIONS...'
foreach($my_file in Get-ChildItem $list){Install-SPSolution -Identity $my_file.Name -AllWebApplications -GACDeployment}
Is there a way to check if the deployment is finished, and it is ready to start installing the solutions?
You need to check the SPSolution.Deployed property value in a loop - basic solution looks like this:
do { Start-Sleep 2 } while (!((Get-SPSolution $name).Deployed))
The Deploying SharePoint 2010 Solution Packages Using PowerShell article contains more details and this comment discusses a potential caveat.

Get dbname from multiple web.config files with powershell

I would like to issue a powershell command to return me the connection string (specifically I am looking for the db name value) for all the web sites on a web server...
So I would like to see something like
site1 dbname=Northwind
site2 dbname=Fitch
site3 dbname=DemoDB
I have tried using the IIS Powershell snap-in... I thought I was close with this:
PS C:\Windows\system32> Get-WebApplication | Get-WebConfiguration -filter /connectionStrings/*
but... after looking at the results... my answer doesn't appear to be in there
I am very new to powershell - so excuse my ignornance and inexperience
Any help appreciated!
thanks!
Hopefully, this will get you started. This just assumes there will be a web.config file at the physical path of the web application's physical path. It does not recurse to find other web.config files in the web application. It also assumes your connection strings are in the connectionStrings configuration element.
Import-Module WebAdministration
Get-WebApplication | `
ForEach-Object {
$webConfigFile = [xml](Get-Content "$($_.PhysicalPath)\Web.config")
Write-Host "Web Application: $($_.path)"
foreach($connString in $webConfigFile.configuration.connectionStrings.add)
{
Write-Host "Connection String $($connString.name): $($connString.connectionString)"
$dbRegex = "((Initial\sCatalog)|((Database)))\s*=(?<ic>[a-z\s0-9]+?);"
$found = $connString.connectionString -match $dbRegex
if ($found)
{
Write-Host "Database: $($Matches["ic"])"
}
}
Write-Host " "
}
This post may give you an idea to start with. Basically load in the web.config file as an XML file and then just find the node where the connection string is.
Do something like $myFile = ([xml] Get-Content web.config). You can then pipe that to Get-Member ( $myFile | Get-Member -MemberType Property) to start working your way into the file to see what node has it. I'm not at a computer where I can show you some screenshots to explain it more, but you can check this chapter out from PowerShell.com "Master PowerShell" e-book that explains working with XML very well.

Resources