moving item failing on zero bytes - powershell

Where am I going wrong with the below script...it checks for if files are of zero (0) bytes and then if they are it moves them to a folder.
It works fine outside of the IF statement but when I try it in the below it fails copying the files and displays the below error:
Move-Item : Cannot bind argument to parameter 'Path' because it is
null. At C:\Tools\jon\testing_scheduled.ps1:109 char:11
+ Move-Item <<<< $moving "$scheduledpath\Move_empty"
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
filter gettheheckout([string]$path = '.')
{
$move = Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0} | Foreach-Object {$_.fullName}
}
$moving = gettheheckout
$check = #(Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0})
if ($check.length -eq 0)
{
Write-host = "No files to move - Script Completed" -ForegroundColor Cyan
}
else
{
Move-Item $moving "$scheduledpath\Move_empty"
Write-Host "Script Completed - Use Excel to Filter on commas - Have a nice day!" -ForegroundColor Cyan
}

change this:
filter gettheheckout([string]$path = '.')
{
Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0} | Foreach-Object {$_.fullName}
}
and be sure $scheduledpath is a global scope variable and have a value.

Related

Regex match does not produce desired result

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

PowerShell logon script to log Microsoft Office version

I came across PowerShell script to log Microsoft Office version of remote computer on domain. I want to run it as logon script to I modified OpenRemoteBaseKey to OpenBaseKey and this is the code:
$version = 0
$reg = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Default')
$reg.OpenSubKey('software\Microsoft\Office').GetSubKeyNames() |% {
if ($_ -match '(\d+)\.') {
if ([int]$matches[1] -gt $version) {
$version = $matches[1]
}
}
}
if ($version) {
Add-Content -Path \\server\share\oversion.txt -Value "$env:computername $env:username : $version"
}
else {
Add-Content -Path \\server\share\oversion.txt -Value "$env:computername $env:username : 0"
}
but now I receive error:
You cannot call a method on a null-valued expression.
At line:4 char:1
+ $reg.OpenSubKey('software\Microsoft\Office').GetSubKeyNames() |% {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
but not sure what this means since GetSubKeyNames seems valid: https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registrykey.getsubkeynames?view=netframework-4.7.2, also it works with OpenRemoteBaseKey, can someone point me to right direction, please?
I'm not sure why OpenRemoteBaseKey works, but OpenBaseKey doesn't because I cannot reproduce that..
You might however try the more Powershell way of doing this:
$version = 0
Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Office' -Name | Where-Object {$_ -match '(\d+)\.\d+'} | ForEach-Object {
$version = [math]::Max([int]$_, $version)
}
Add-Content -Path \\server\share\oversion.txt -Value "$env:COMPUTERNAME $env:USERNAME : $version"

Using if condition to compare in PowerShell

I am trying to get the .Net version from the system and trying to check does my system have .Net version greater than or equal to 4.6 or not. Below is the code. From the code I am able to retrieve the release version. I am facing a problem in the if condition.
$myArray = #()
$myArray = #(Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Release,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}' } |
Select Release)
Write-Output $myArray[0]
Write-Output $myArray[1]
$var1 = 393295
foreach ($var in $myArray) {
Write-Output $var
if ($var -ge $var1) {
Write-Output same
} else {
Write-Output NOT same
}
}
I am getting this error:
Cannot compare "#{Release=461808}" to "393295" because the objects are not the
same type or the object "#{Release=461808}" does not implement "IComparable".
At C:\Users\Desktop\DotNet.ps1:13 char:9
+ if ($var -ge $var1) {
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : PSObjectCompareTo
Change the foreach line as
foreach($var in $myArray.Release)

Path not found when using Move-Item

I want to do to the following things:
do the listing of all the items in the directory
move the files according to their names into different location
Example: In my document folder I have various files. According to the file names, I will move them to different directory. I use the following script. But it is not working.
$allfiles = Get-ChildItem $home\documents
$count = 0
foreach($file in $allfiles)
{
if ($file.name -like "*Mama*")
{
move-item $file.name -Destination $home\documents\mom
$count++
}
elseif ($file.name -like "*Papa*")
{
move-item -destination $home\documents\Dad
$count++
}
elseif ($file.name -like "*bro")
{
Move-Item -Destination $home\documents\Brother
$count++
}
}
write-host "$count files been moved"
What I am doing wrong here?
My Error output is
move-item : Cannot find path 'C:\users\administrator\documents\Lecture3.txt' because it does not exist.
At line:6 char:10
{ move-item $file.name -Destination $home\documents\Win213SGG\lectures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ObjectNotFound: (C:\users\admini...ts\Lecture3.txt:String) [Move-Item], ItemNotFoundExceptio
n
FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
move-item : Cannot find path 'C:\users\administrator\documents\Lecture3_revised.txt' because it does not exist.
At line:6 char:10
+ { move-item $file.name -Destination $home\documents\Win213SGG\lectures
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\users\admini...re3_revised.txt:String) [Move-Item], ItemNotFoundExceptio
n
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
cmdlet Move-Item at command pipeline position 1
Supply values for the following parameters:
Path[0]:
Or you could make it even neater by using the pipe functionality in powershell. Like this, you don't have to specify with '-path' which file to move, but you can pass it on directly from the result of Get-ChildItem:
Get-ChildItem $home\documents | Foreach-Object {
$count = 0
if ($_.Name -like "*Mama*")
{
$_ | Move-Item -Destination $home\documents\mom
$count++
}
elseif ($_.Name -like "*Papa*")
{
$_ | Move-Item -Destination $home\documents\Dad
$count++
}
elseif ($_.Name -like "*bro")
{
$_ | Move-Item -Destination $home\documents\Brother
$count++
}
}
write-host "$count files been moved"
Try this -
$allfiles = Get-ChildItem $home\documents
$count = 0
foreach($file in $allfiles)
{
if ($file.name -like "*Mama*")
{
move-item -path $file -Destination $home\documents\mom
$count++
}
elseif ($file.name -like "*Papa*")
{
move-item -path $file -destination $home\documents\Dad
$count++
}
elseif ($file.name -like "*bro")
{
Move-Item -path $file -Destination $home\documents\Brother
$count++
}
}
write-host "$count files been moved"
You haven't specified the File Name at two occasions which is a mandatory parameter for move-item. And at one place you are trying to move the files using the Name parameter which is not an item(in literal sense). See if above works for you.

get-childitem : Cannot find path ' ' because it does not exist

I am trying to make a script that can report on a folder size for a specified folder.
I keep getting this error after I put in the folder name and I know the folder exists.
Also if I don't get this error then I always get 0 MB.
get-childitem : Cannot find path 'C:\WINDOWS\system32\downloads' because it does not exist.
At C:\Users\Erik\Desktop\powershell script.ps1:58 char:12
+ $folders = get-childitem $startfolder | where{$_.PSiscontainer -eq "T ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\WINDOWS\system32\downloads:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound, Microsoft.PowerShell.Commands.GetChildItemCommand
Code
$startfolder = Read-Host -Prompt 'Please enter the folder name:'
#check that input is not empty
if([string]::IsNullOrEmpty($startfolder)) {
Write-Host "folder name is NULL or EMPTY"
} else {
$folders = get-childitem $startfolder | where {$_.PSiscontainer -eq "True"}
"folder Name`tfolder Size (MB)"
foreach ($fol in $Folders) {
$colItems = (Get-ChildItem $fol.fullname -recurse | Measure-Object -property length -sum)
$size = "{0:N2}" -f ($colItems.sum / 1MB)
"$($fol.name)`t$size"
}
}
so.. My power-shell is a bit terrible but I've got this working for me:
$startfolder = Read-Host -Prompt 'Please enter the folder name:'
#check that input is not empty
if([string]::IsNullOrEmpty($startfolder)) {
Write-Host "folder name is NULL or EMPTY"
}
else {
$subFolderItems = Get-ChildItem $startfolder.FullName -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
$startfolder + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB"
}
the output is like:
test -- 2.65 MB