in jenkins(windows), powershell ls pipeline get null - powershell

This is my jenkins script.
Without pipeline, can see ls result list.
but when include pipeline with foreach, assign null to '$_'. Why??
stage('Module Build'){
gitlabCommitStatus('Module Build'){
powershell "${pythonPath} -m compileall ${srcPath}"
powershell "ls ${srcPath}\\*.py -Recurse | foreach {rm $_}"
}
}
error log
d:\...\durable-51664e76\powershellScript.ps1:1 char:33
+ ls src\*.py -Recurse | foreach {rm "null"}
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (D:\Jenkins\work...istributor\nu
ll:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.Remov
eItemCommand

Try changing syntax to foreach-object
powershell "ls ${srcPath}\\*.py -Recurse | %{rm $_}"
further reading:
Difference between ForEach and ForEach-Object in powershell

Related

Bulk renaming files to add sequential prefixes via PowerShell

I have two folders all with multiple .msg files I need to add a numerical, sequential prefix to. One folder has over 1500 individual files.
I want the end result to go from this:
"[EXTERNAL] RE%3A Auth....msg"
"Fees....msg"
"Hello There...msg"
To this:
"1[EXTERNAL] RE%3A Auth....msg"
"2Fees....msg"
"3Hello There...msg"
I have tried to combine a few results from other similar threads I have found here and have come up with the following:
$i = 1
#Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.directory.name).msg" -f $i++)}
When I run this script, I get the following errors:
At C:\users\me\Documents\PrependNumbers.ps1:10 char:5
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~~~~~~~
Unexpected token '-ChildItem' in expression or statement.
At C:\users\me\Documents\PrependNumbers.ps1:10 char:16
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~~
Unexpected token '*.msg' in expression or statement.
At C:\users\me\Documents\PrependNumbers.ps1:10 char:1
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~
The splatting operator '#' cannot be used to reference variables in an expression. '#Get' can be used only as an
argument to a command. To reference variables in an expression use '$Get'.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
I feel like I probably just have a syntax error somewhere, but am unable to tell where exactly from these errors.

Issue with foreach + get-childitem

I'm doing a script to organize my media. I download files in one directory to accomodate them before adding to my media center.
If for example I have a file called Breaking.Bad.S01E01.DVDRip.XviD-ORPHEUS.avi I would like the script to get the name of the show, check for season on S01 and move that file to a folder in another disk, for example e:\series\breaking bad\season 01
So far it checks if the file is call s01e01 or S01E01 or s01.e01 or S01.E01 and returns Breaking Bad\Season 01, creates the path to move to and the moving action itself
I have part of that script but I cannot make get-childitem to work with foreach.
This is what I have so far and the error I'm getting:
CODE
$FilesList = Get-ChildItem -name -recurse -include *.mkv,*.mp4,*.srt,*.avi
$FilesList
foreach ($FL_Item in $FilesList)
{
$SeriesName = ($FL_Item.BaseName -split '\.s\d')[0].Replace('.', ' ')
$SE_Info = $FL_Item.BaseName.Split('.')[-3] -split 'e'`
$Season = $SE_Info[0] -replace 's', 'Season '
#$Episode = 'Episode{0}' -f $SE_Info[1]
$SeriesName
$Season
#$Episode
$SeriesDirectory = Join-Path -Path "$SeriesName" -ChildPath "$Season"
$SeriesDirectory
#$MoverArchivo = move-item -path $FileName -destination e:\series\$SeriesDirectory
#$MoverArchivo
''
}
OUTPUT I'm getting
Breaking.Bad.S01E01.DVDRip.XviD-ORPHEUS.avi
Breaking.Bad.S01E01.DVDRip.XviD-ORPHEUS.spa.srt
Breaking.Bad.S04E01.Box.Cutter.720p.hdtv.x264-orenji.mkv
Breaking.Bad.S04E01.Box.Cutter.720p.hdtv.x264-orenji.spa.srt
Breaking.Bad.S05E15.720p.HDTV.x264-EVOLVE.mkv
Breaking.Bad.S05E15.720p.HDTV.x264-EVOLVE.spa.srt
Path Of Blood (2018) [WEBRip] [1080p] [YTS.AM]\Path.Of.Blood.2018.1080p.WEBRip.x264-[YTS.AM].mp4
They Shall Not Grow Old (2018) [BluRay] [1080p] [YTS.AM]\They.Shall.Not.Grow.Old.2018.1080p.BluRay.x264-[YTS.AM].mp4
ERROR
You cannot call a method on a null-valued expression.
At D:\shared\temp\test3.ps1:8 char:5
+ $SE_Info = $FL_Item.BaseName.Split('.')[-3] -split 'e'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Cannot index into a null array.
At D:\shared\temp\test3.ps1:10 char:5
+ $Season = $SE_Info[0] -replace 's', 'Season '
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Join-Path : Cannot bind argument to parameter 'Path' because it is an empty string.
At D:\shared\temp\test3.ps1:17 char:37
+ $SeriesDirectory = Join-Path -Path "$SeriesName" -ChildPath "$Sea ...
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Join-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.Join
PathCommand
Any ideas what could be wrong?
You are using the -name parameter of Get-ChildItem in your first line:
$FilesList = Get-ChildItem -name -recurse -include *.mkv,*.mp4,*.srt,*.avi
which means it will return just the names of the files as strings.
Later, in your loop, you access each element using the BaseName property, which is a property of FileInfo objects, not strings. So, $FL_Item.BaseName returns an empty string and you get the errors as shown.
Just remove the -name and it should work (or at least you won't get those errors).
I'd use a RegEx with (named) capture groups to grep the Series,Season and Episode number.
See the RegEx working live on regex101.com
## Q:\Test\2018\12\20\SO_53875674.ps1
$DstBase = "E:\series"
Get-ChildItem -Include *.mkv,*.mp4,*.srt,*.avi -Recurse -File|
Where-Object BaseName -match "^(?<Series>.*?)\.?S(?<Season>\d{1,2})\.?E(?<Episode>\d{2})"|
ForEach-Object {
$Destination = "{0}\{1}\Season {2:00}\" -f $DstBase,$Matches.Series.replace('.',' ').Trim(),[int]$Matches.Season
if (!(Test-Path $Destination)){MD $Destination -Force | Out-Null}
"Moving file [{0}] to [{1}]" -f $_.FullName,$Destination
$_ | Move-Item -Destination $Destination -Force
}
Sample tree (with above data) after running the script:
> tree /F
└───series
└───Breaking Bad
├───Season 01
│ Breaking.Bad.S01E01.DVDRip.XviD-ORPHEUS.avi
│ Breaking.Bad.S01E01.DVDRip.XviD-ORPHEUS.spa.srt
│
├───Season 04
│ Breaking.Bad.S04E01.Box.Cutter.720p.hdtv.x264-orenji.mkv
│ Breaking.Bad.S04E01.Box.Cutter.720p.hdtv.x264-orenji.spa.srt
│
└───Season 05
Breaking.Bad.S05E15.720p.HDTV.x264-EVOLVE.mkv
Breaking.Bad.S05E15.720p.HDTV.x264-EVOLVE.spa.srt

powershell from chef resource powershell_script

I am trying to use one var declared outside chef resource powershell_script.
cn_name = powershell.exe hostname
puts cn_name ## will print like WIN-I5NP98N6JUE.cpteam.local
Now , i am trying to get the thumbprint of the root CA cert installed in this host.
powershell_script 'import CA_cert' do
code <<-EOH
$Thumbprint = (Get-ChildItem -Path Cert:\\LocalMachine\\Root | Where-Object {$_.Subject -match "CN="#{cn_name}""}).Thumbprint;
EOH
end
This is printing like : + ... ct -match "CN="WIN-I5NP98N6JUEcpteam.local""}).Thumbprint;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token 'WIN-I5NP98N6JUEcpteam.local""' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Kindly help me here how to escape those quotes./ before quotes doesnt work.
Thanks!
That should be {$_.Subject -match "CN=#{cn_name}"}), you don't need the extra quotes at all.
try this to escape your extra quotes:
$Thumbprint = (Get-ChildItem -Path Cert:\\LocalMachine\\Root | Where-Object {$_.Subject -match "CN=`"#{cn_name}`""}).Thumbprint;

PowerShell: I need to understand why parameters are interpreted as NULL

I'm getting an error that I can't call a method on a null valued expression. However, I'm not sure WHY the parameters are resulting in a null value. I need a second set of eyes to look at this and give me some guidance.
$docpath = "c:\users\x\desktop\do"
$htmPath = "c:\users\x\desktop\ht"
$txtPath = "c:\users\x\desktop\tx"
$srcPath = "c:\users\x\desktop\ht"
#
$srcfilesTXT = Get-ChildItem $txtPath -filter "*.htm*"
$srcfilesDOC = Get-ChildItem $docPath -filter "*.htm*"
$srcfilesHTM = Get-ChildItem $htmPath -filter "*.htm*"
#
function rename-documents ($docs) {
Move-Item -txtPath $_.FullName $_.Name.Replace("\.htm", ".txt")
Move-Item -docpath $_.FullName $_.Name.Replace("\.htm", ".doc")
}
ForEach ($doc in $srcpath) {
Write-Host "Renaming :" $doc.FullName
rename-documents -docs $doc.FullName
$doc = $null
}
And the error....
You cannot call a method on a null-valued expression.
At C:\users\x\desktop\foo002.ps1:62 char:51
+ Move-Item -txtPath $_.FullName $_.FullName.Replace <<<< ("\.htm", ".txt")
+ CategoryInfo : InvalidOperation: (Replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\users\x46332\desktop\foo002.ps1:63 char:51
+ Move-Item -docpath $_.FullName $_.FullName.Replace <<<< ("\.htm", ".doc")
+ CategoryInfo : InvalidOperation: (Replace:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
First: it appears that my ("\.htm", ".txt") is what's showing up as null. I've tried it without the \ - (".htm", ".txt") - as well and received the same results.
Second: syntactically, I'm interpreting my line as move-item <path> <source-file-passed-to-function> <replacement=name-for-file> (parameters-for-replacement). Is that an appropriate understanding of what this code is doing?
Third: Do I need to have a -literalpath parameter in there somewhere? MS TechNet and get-help have very little information on the uses of the -literalpath parameter; I was unable to find something relevant to my particular situation.
Help me understand what I'm missing. Thanks!
In the context of a simple function $_ is not defined. $_ is only valid in a pipeline. That is, $_ reprensents the current object being passed down the pipeline.
With your current function definition try it this way:
function Rename-HtmlDocument([System.IO.FileInfo]$docs, $newExt) {
$docs | Move-Item -Dest {$_.FullName -replace '\.htm$', $newExt}
}
You can pass this function the $srcfilesDOC and $srcFilesTXT variables directly e.g.:
Rename-HtmlDocument $srcFilesDOC .doc
Rename-HtmlDocument $srcFilesTXT .txt
Of course you could make this more generic and get the source extension from the FileInfo object e.g.:
function Rename-DocumentExtension([System.IO.FileInfo]$docs, $newExt) {
$docs | Move-Item -Dest {$_.FullName.Replace($_.Extension, $newExt)}
}
BTW PowerShell's Move-Item command doesn't have the parameters you're using -txtPath and -docPath. Is this a function you've created?

Powershell WMI Query failing when executed from Task Scheduler

i have a strange problem...
i have the following code, which takes the output from Sysinternals Disk Usage tool (link below)
Disk Usage - Sys Internals
so first i get the physical drives into array $Disks, then i enumerate these through the foreach and mess about with them.
my problem lies in this line $Dir = du.exe -q -v $d.DeviceID
$PC = get-content env:COMPUTERNAME
$Disk = gwmi win32_logicaldisk -filter "drivetype=3"
foreach ($d in $Disk)
{
$Dir = du.exe -q -v $d.DeviceID
$Dir[8..($Dir.length-8)] | foreach {
$Size = $_.substring(0,10).replace(",","")/1024
$Path = $_.substring(10)
}
}
$d.DeviceID should be the drive letter (i.e. C:)
then i populate $Dir with the output from DU.exe, but $d.DeviceID is not acting how it is supposed to, running this from a task has this following result (added a line that says $d.DeviceID, to show the output):
B:
Cannot index into a null array.
At C:\DU.ps1:25 char:6
+ $Dir[ <<<< 8..($Dir.length-8)] | foreach {
+ CategoryInfo : InvalidOperation: (System.Object[]:Object[]) [],
RuntimeException
+ FullyQualifiedErrorId : NullArray
C:
Cannot index into a null array.
At C:\DU.ps1:25 char:6
+ $Dir[ <<<< 8..($Dir.length-8)] | foreach {
+ CategoryInfo : InvalidOperation: (System.Object[]:Object[]) [],
RuntimeException
+ FullyQualifiedErrorId : NullArray
D:
Cannot index into a null array.
At C:\DU.ps1:25 char:6
+ $Dir[ <<<< 8..($Dir.length-8)] | foreach {
+ CategoryInfo : InvalidOperation: (System.Object[]:Object[]) [],
RuntimeException
+ FullyQualifiedErrorId : NullArray
running it from the ISE or just from the Shell has no issues, running it on other servers from all methods works.
i do believe the population of the $Dir vairable is the problem, as the du.exe has trouble with the $d.DeviceID
i dont understand why it is just this server/task sheduler that has the issue. i have tried the following:
redefined the array element to $i = $d.deviceID to fix it down - nothing
exported the job from other server (both DCs) an imported - nothing
restarted the winmgmt service - nothing
i think its a permissions issue, but im running this on an AD as THE Dom Admin with top privilages.
please can you guys help on this one, really am stuck...
cheers
Lee
Yet another update based on comment below:
Try:
$cmd = "du.exe `-q `-v $($d.DeviceID)"
$dir = Invoke-Expression $cmd
Updating as per the comment below.
Take this example. This can get the size of every folder and display size and full path to the folder.
Function Get-FolderSize {
Param ($folderPath)
$colItems = (Get-ChildItem $folderPath -recurse | Measure-Object -property length -sum)
return $colItems.sum/1MB
}
$folders = Get-ChildItem -Recurse C:\Scripts
$folders | % {
if ($_.PSIsContainer) {
$size = Get-FolderSize $_.FullName
Write-Host $size
Write-Host $_.FullName
}
}
You can use WMI to get the drive letter and pass it to the script. For example:
$disks = gwmi win32_logicaldisk -filter "drivetype=3"
$disks | % {
$items = Get-ChildItem -Recurse $_.DeviceID -Force
$items | % {
if ($_.PSIsContainer) {
$size = Get-FolderSize $_.FullName
Write-Host $size
Write-Host $_.FullName
}
}
}
So, with this, you dont need DU.exe. You can run this as a script.
--------------OLD ANSWER _-------------------
First thing I would suspect is the path to DU.exe. What is the working directory set on the scheduled task? Is it the place where DU.exe is available?
BTW, what is the goal of this script? Are you just looking at the disk drive size? What are you capturing into $path? I did not have the patience to test your code. But, I feel that this can be easily achieved using just WMI and no other external tools.