Regex match does not produce desired result - powershell

This regex match
$script:lstfilepath = ((Get-Content -path $script:ordfile) | Select-String -pattern "^file\s*=\s*(\\\\.*.lst)").matches.groups[1].value
Produces this error on files that do not contain the match, leaving me to believe the return is null.
Cannot index into a null array.
At line:1 char:1
+ ((Get-Content -path .\27257055-brtcop.ORD) | Select-String -pattern " ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Yet my script never jumps to the "else", it processes everything under the "if" even if there is no match.
$script:lstfilepath = ((Get-Content -path $script:ordfile) | Select-String -pattern "^file\s*=\s*(\\\\.*.lst)").matches.groups[1].value
if (-not ([string]::IsNullOrEmpty($script:lstfilepath)))
{
###LST PROCESS
Write-Host "LST FILE PRESENT"
$script:lstpayload = Get-Content $script:lstfilepath |ForEach-Object { ($_ -split '"')[-2] }
FOREACH ($script:lstfile in $script:lstpayload)
{
$script:lstzipshortname = (-join ((48..57) + (97..122) |get-random -count 11 |% {[char]$_}))
$script:lstzipname = $script:lstzipshortname + ".zip"
7z a -spf $script:lstzipname $script:lstfile
}
Set-Location $global:ordprocessingpath
copy-item -Recurse $script:ordprocfolder c:\temp
}
else
{
###REGULAR PROCESS
$script:filepath = ((Get-Content -path $script:ordfile) | Select-String -pattern "^file\s*=\s*(\\\\.*\\)").matches.groups[1].value
$script:zipshortname = $script:ordfile
$script:zipname = $script:zipshortname + ".zip"
7z a -spf $script:zipname $script:filepath
}
EDIT:FULL SCRIPT FOR AoT
$global:ordrepopath = "C:\test_environment\ORD_REPO"
$env:path = "c:\program files\7-zip"
$global:datestr = (Get-Date).ToString("MMddyyyyhhmmss")
$global:ordlogpath = "C:\test_environment\ORD_REPO\ORD_LOGS\"
$global:ordlogcheck = "C:\test_environment\ORD_REPO\ORD_LOGS\*.log"
$global:ordlogstagingpath = "C:\test_environment\ORD_REPO\ORD_STAGING"
$global:ordlogarchivepath = "C:\test_environment\ORD_REPO\ORD_LOG_ARCHIVE"
$global:ordprocessingpath = "C:\test_environment\ORD_REPO\ORD_PROCESSING"
$global:copypath = "C:\test_environment_2\share\STAGING\PRE_STAGING"
$global:ordlogdestpath = "C:\test_environment_2\Share\Staging\Pre_staging\processed_logs"
###DEFINE LOG FILE
$script:scriptlogfile = "C:\test_environment\ORD_REPO\SCRIPT_LOGS\ORD_PROCESS_LOG_$(get-date -format `"yyyyMMdd_hhmmss`").log"
Start-Transcript -Path $script:scriptlogfile -NoClobber
if (!(Test-Path -Path $global:ordlogcheck))
{
Write-Host "NO FILES TO PROCESS"
}
else
{
### CREATE ARCHIVE DIRECTORY
New-Item -Path "C:\test_environment\ORD_REPO\Archive\$global:datestr" -ItemType Directory
$script:archivepath = "C:\test_environment\ORD_REPO\Archive\$global:datestr"
$script:ordlogfiles = Get-ChildItem -Path $global:ordlogpath -File
ForEach ($script:ordlogfile in $script:ordlogfiles)
{
Set-Location $global:ordlogpath
$script:ordlogimport = (Import-Csv $script:ordlogfile.FullName).file |sort
$script:ordprocfoldername = ($script:ordlogimport |Select-Object -First 1)
New-Item -Path "C:\test_environment\ORD_REPO\ORD_PROCESSING\$script:ordprocfoldername" -ItemType Directory
$script:ordprocfolder = "C:\test_environment\ORD_REPO\ORD_PROCESSING\$script:ordprocfoldername"
Set-Location $global:ordrepopath
$script:ordlogimport |ForEach-Object {move-item $_ $script:ordprocfolder}
Set-Location $global:ordlogpath
copy-item $script:ordlogfile $script:archivepath
move-item $script:ordlogfile $script:ordprocfolder
Set-Location $script:ordprocfolder
$script:ordfiles = Get-ChildItem $script:ordprocfolder -Include *.ord,*.nwp | ForEach-Object { $_.Name }
FOREACH ($script:ordfile in $script:ordfiles)
{
$script:ordlogcount = ($script:ordlogimport).count
$script:ordcount = ((get-childitem $script:ordprocfolder).count -1)
if ($script:ordlogcount -ne $script:ordcount)
{
WRITE-HOST "MISSING ORD FILE"
}
else
{
$script:lstfilepath = ((Get-Content -path $script:ordfile) | Select-String -pattern "^file\s*=\s*(\\\\.*.lst)").matches.groups[1].value
if (-not ([string]::IsNullOrEmpty($script:lstfilepath)))
{
###LST PROCESS
Write-Host "LST FILE PRESENT"
$script:lstpayload = Get-Content $script:lstfilepath |ForEach-Object { ($_ -split '"')[-2] }
FOREACH ($script:lstfile in $script:lstpayload)
{
$script:lstzipshortname = (-join ((48..57) + (97..122) |get-random -count 11 |% {[char]$_}))
$script:lstzipname = $script:lstzipshortname + ".zip"
7z a -spf $script:lstzipname $script:lstfile
}
Set-Location $global:ordprocessingpath
copy-item -Recurse $script:ordprocfolder c:\temp
}
else
{
###REGULAR PROCESS
$script:filepath = ((Get-Content -path $script:ordfile) | Select-String -pattern "^file\s*=\s*(\\\\.*\\)").matches.groups[1].value
$script:zipshortname = $script:ordfile
$script:zipname = $script:zipshortname + ".zip"
7z a -spf $script:zipname $script:filepath
}
}
}
}
}

If $script:lstfilepath has a previous value, the error produced by your Select-String will not overwrite the value. Therefore, you need to purge the contents of $script:lstfilepath before this code executes or declare it again. Below is a replication of your issue.
$g = "hi"
$g = (select-string -pattern "h(h)" -InputObject "tree").matches.groups[1].value
Cannot index into a null array.
At line:1 char:1
+ $g = (select-string -pattern "h(h)" -InputObject "tree").matches.grou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
-not ([string]::IsNullOrEmpty($g))
True
$g
hi
Here is one way to solve that issue using Clear-Variable:
$g
hi
Clear-Variable g
$g = (select-string -pattern "h(h)" -InputObject "tree").matches.groups[1].value
Cannot index into a null array.
At line:1 char:1
+ $g = (select-string -pattern "h(h)" -InputObject "tree").matches.grou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
-not ([string]::IsNullOrEmpty($g))
False

Related

Move Item path null

I have to move files from a folder corresponding to a CSV column like that :
id
name
1a
file1
2b
file2
3c
file3
4d
file4
So if in my folder I have a file named file1 I need to create a folder named 1a and put file1 inside.
I have the following script
$CsvId = Import-Csv './test.csv'
$sourcePath= "C:\Users\olong\Desktop\object"
$dirPath = "C:\Users\olong\Desktop\dir"
$files = Get-ChildItem -Path $sourcePath | ForEach-Object -Process {[System.IO.Path]::GetFileNameWithoutExtension($_)}
$pattern = '(?<=_).*(?=_)'
ForEach ($item In $CsvId) {
$objectID = $item.'id'
$docID = $item.'name'
$location = $dirPath+ "\" + $objectID
Foreach ($file in $files) {
if($file -contains $docID) {
if (-not (Test-Path -Path $location)) {
mkdir -Path $location
}
Move-Item ($file.FullName) -Destination $location -Verbose -Force
}
}
}
But it gives me that error :
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\olong\Desktop\scriptMove.ps1:19 char:15
+ Move-Item ($file.FullName) -Destination $location -Verbose -Force
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
With PowerShell's debugger $file is not null and with or without parenthesis on $file.FullName does nothing
I think what you want to do is to get the file(s) as mentioned in the csv under header 'name' having any extension into a subfolder as mentioned in field 'id' and create that subfolder first if it does not already exist.
If my assumtion is correct, you can try below:
$sourcePath = "C:\Users\olong\Desktop\object"
$destinationPath = "C:\Users\olong\Desktop\dir"
Import-Csv -Path './test.csv' | ForEach-Object {
$targetDirectory = Join-Path -Path $destinationPath -ChildPath $_.id
# create the output subfolder if it does not already exist
$null = New-Item -Path $targetDirectory -ItemType Directory -Force
# next use the file basename from the $_.name column as filter and move the file(s)
Get-ChildItem -Path $sourcePath -Filter "$($_.name).*" -File | Move-Item -Destination $targetDirectory
}

Error while running powershell script

I want to remove bak files after zip from all subfolder for given path, so all duplicate files with extension .bak will be removed,i run below script but getting error.
$filePath = "d:\Test\"
$Afiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".bak"}
$Bfiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".7z"}
$Alist = #()
$Blist = #()
foreach( $A in $Afiles) {
$Alist += $A.baseName
}
foreach( $B in $Bfiles) {
$Blist += $B.baseName
}
foreach($A in $Alist) {
if($Blist -contains $a)
{
rm ("$A.bak")
}
}
I am receiving below error :
Remove-Item : Cannot find path 'C:\Users\******\Desktop\master_backup_2015_08_21_013722_8370267.bak' because it does not exist.
At C:\Users\*****\Desktop\duplicatedelete1.ps1:26 char:10
+ rm <<<< ("$A.bak")
+ CategoryInfo : ObjectNotFound: (C:\Users\****....722_8370267.bak:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
You're receiving error because you're not specifying full path for rm command and PowerShell tries to delete file in your current directory.
Try this:
$Path = 'D:\Test'
Get-ChildItem -Path $Path -Recurse -Filter '*.7z' | ForEach-Object {
$BackupFile = Join-Path -Path (Split-Path $_.FullName -Parent) -ChildPath ($_.BaseName + '.bak')
if(Test-Path -Path $BackupFile){
Remove-Item -Path $BackupFile
}
}

Powershell mystical error

Please help! i'm confused what to do.
Script split files by content:
$InPC = "C:\Scripts\"
Get-ChildItem $InPC -Filter *.prt | ForEach-Object -Process {
$basename= $_.BaseName
$m = ( ( Get-Content $_ | Where { $_ | Select-String "--------------------- Instance Type and Transmission --------------" -Quiet } | Measure-Object | ForEach-Object { $_.Count } ) -ge 2)
$a=1
if ($m) {
Get-Content $_ | % {
If ($_ -match "--------------------- Instance Type and Transmission --------------") {
$OutputFile = "$basename-$a.prt"
$a++
}
Add-Content $OutputFile $_
}
Remove-Item $_
}
}
Everything is going OK when i'm set-location to C:\Scripts. But in base case it won't work and give next error:
Get-Content : Path not found "C:\Users\a.ulianov\PRTPRT.prt".
C:\Scripts\2.ps1:23 знак:18
+ $m = ( ( Get-Content $_ | Where { $_ | Select-String "------------------ ...
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\a.ulianov\PRTPRT.prt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Get-Content : Path not found "C:\Users\a.ulianov\test.prt".
C:\Scripts\2.ps1:23 знак:18
+ $m = ( ( Get-Content $_ | Where { $_ | Select-String "------------------ ...
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\a.ulianov\test.prt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
it's seems to work with default PS location during excuting. What i might modify in this case?
#
thanks to #Raf #Rynant here is little crooked but working solution:
$InPC = "C:\Scripts"
Get-ChildItem -Path $InPC -Filter *.prt | ForEach-Object -Process {
$basename= $_.BaseName
$m = ( ( Get-Content $_.FullName | Where { $_ | Select-String "--------------------- Instance Type and Transmission --------------" -Quiet } | Measure-Object | ForEach-Object { $_.Count } ) -ge 2)
$a = 1
if ($m) {
Get-Content $_.FullName | % {
If ($_ -match "--------------------- Instance Type and Transmission --------------") {
$OutputFile = "$InPC\$basename _$a.prt"
$a++
}
Add-Content $OutputFile $_
}
Remove-Item $_.FullName
}
}
Looks a bit messy but I think the only change you need to do is replace:
Get-Content $_
with
Get-Content $_.FullName

Cannot bind argument to parameter 'Path' because it is null: but I can't spot the error

This is my code but i dont know what i need to supply:
$ServerList = Get-Content "C:\Users\munjanga\Desktop\Execute\Testing\servers.txt"
$ServerList
$Header="FolderPath,IdentityReference,AccessControlType,IsInherited,InheritedFlags,PropagationFlags"
Add-Content -Value $Header -Path $Output
Foreach ($Server in $ServerList) {
$output = "\\$server\C:\Users\munjanga\Desktop\Execute\Testing $server.output.csv"
Del $Output -ErrorAction SilentlyContinue
$RootPath ="\\$Server\C:\system.sav"
$Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true} -ErrorAction SilentlyContinue
Add-Content -Value "$Header" -Path $Output
Foreach ($Folder in $Folders){
$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
$OutInfo = $Folder.Fullname + "," + $ACL.IdentityReference + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
Add-Content -Value $OutInfo -Path $output -ErrorAction SilentlyContinue
}
}
}
In line 4 you are invoking the Add-Content cmdlet, which requires a something to be passed to -Path, you are trying to use $Output, which is an empty (null) variable.
Assuming you are getting the warning on line 12 when calling Where-Object? It looks like you are trying to do a directory listing on a unc path that doesnt exist, getting nothing back to pipe to where. Is \$Server\C:\system.sav really supposed to be the admin share a la \$Server\C$\system.sav ?

Powershell path not taking string variable

I am using the following code to select a folder through the Windows Forms "Browse" function and then pass that path to the gci cmdlet
cls
Function Get-Directory($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$OpenfolderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$OpenfolderDialog.RootFolder = $initialDirectory
$OpenfolderDialog.ShowDialog()| Out-Null
$StartDir = $OpenfolderDialog.SelectedPath
Return $StartDir | Out-String
}
$myDir = Get-Directory -initialDirectory "Desktop"
$Child = gci -path $mydir -r -Filter *.jpg
Foreach ($item in $Child) {Move-Item -path $item.pspath -Destination $myDir -Force}
but I get these errors:
***At C:\Test\Combine Pics2.ps1:17 char:13
+ $Child = gci <<<< -path $mydir -r -Filter *.jpg
+ CategoryInfo : ObjectNotFound: (C:\Test
:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Test\Combine Pics2.ps1:19 char:43
+ Foreach ($item in $Child) {Move-Item -path <<<< $item.pspath -Destination $myDir -Force}
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand***
The $myDir variable is of type String, why does it not pass to the -path parameter.
What if the user canceled the dialog? Give this a try:
Function Get-Directory($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenfolderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$OpenfolderDialog.RootFolder = $initialDirectory
$result = $OpenfolderDialog.ShowDialog()
if($result -eq 'ok')
{
$OpenfolderDialog.SelectedPath
}
else
{
"canceled"
}
}
$mydir = Get-Directory -initialDirectory Desktop
if($mydir -ne 'canceled')
{
gci -path $mydir
}
Try this:
Function Get-Directory($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$OpenfolderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$OpenfolderDialog.RootFolder = $initialDirectory
if ($OpenfolderDialog.ShowDialog() -eq "OK") {
#Continue only if a folder was selected
$OpenfolderDialog.SelectedPath
}
}
$myDir = Get-Directory -initialDirectory "Desktop"
#Continue only if a folder was selected
if($myDir) {
$Child = Get-ChildItem -path $mydir -Recurse -Filter *.jpg
Foreach ($item in $Child) {
Move-Item -path $item.pspath -Destination $myDir -Force
}
}
I cleaned it up with a few if-tests so it doesn't return errors when people cancel the dialog. There was no need to Out-String as SelectedPath returns a single string by itself.
I got a newline and carriage return at the end of the $mydir value, so try trimming with something like this to see if that is your issue:
$Child = gci -path $mydir.Trim("`r`n") -r -Filter *.jpg
Update: Better yet, just lose the Out-String in your function:
Return $StartDir