Using PowerShell to replicate right clicking a folder and selecting properties - powershell

I am trying to gather the Size/Size on disk and number of files/folders on a very large folder tree.
I have been using a script like the follow to gather some of this:
Get-ChildItem "C:\test" -recurse | Measure-Object -Sum Length | Select-Object `
#{Name="Path"; Expression={$directory.FullName}},
#{Name="Files"; Expression={$_.Count}},
#{Name="Size"; Expression={$_.Sum}}
Path Files Size
---- ----- ----
C:\test 470 11622961
But when I want to gather information on the number of folders and size on disk I'm having to run a separate script; which recuse through the folder tee again (Which takes a long time).
Is there an easy way of accessing the all this information the same way you can get it when you right click a folder and select properties shown below?
Are there any callable .exe files within system32 that can do this?

According to this answer in the Technet forums you can calculate the size on disk like this:
$afz = [MidpointRounding]::AwayFromZero
[math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
$clusterSize can be determined with the fsutil command (e.g. for drive C:):
PS C:\> fsutil fsinfo ntfsinfo C:\
NTFS Volume Serial Number : 0x648ac3ae16817308
Version : 3.1
Number Sectors : 0x00000000027ccfff
Total Clusters : 0x00000000004f99ff
Free Clusters : 0x0000000000158776
Total Reserved : 0x00000000000003e0
Bytes Per Sector : 512
Bytes Per Physical Sector : 512
Bytes Per Cluster : 4096
Bytes Per FileRecord Segment : 1024
Clusters Per FileRecord Segment : 0
...
Note that running fsutil requires admin privileges.
With that you can collect the information you're interested in like this:
$rootDir = "C:\test"
$afz = [MidpointRounding]::AwayFromZero
$clusterSize = fsutil fsinfo ntfsinfo (Get-Item $rootDir).PSDrive.Root `
| Select-String 'Bytes Per Cluster' `
| % { $_.ToString().Split(':')[1].Trim() }
$stat = Get-ChildItem $rootDir -Recurse -Force `
| select Name, Length, #{n="PhysicalSize";e={
[math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
}}, #{n="Folder";e={[int]($_.PSIsContainer)}},
#{n="File";e={[int](-not $_.PSIsContainer)}} `
| Measure-Object -Sum Length, PhysicalSize, Folder, File
$folder = New-Object -TypeName PSObject -Property #{
"FullName" = $rootDir;
"Files" = ($stat | ? { $_.Property -eq "File" }).Sum;
"Folders" = ($stat | ? { $_.Property -eq "Folder" }).Sum;
"Size" = ($stat | ? { $_.Property -eq "Length" }).Sum;
"SizeOnDisk" = ($stat | ? { $_.Property -eq "PhysicalSize" }).Sum - $clusterSize;
}

You're going to have to accumulate your data in a custom object as you see each item:
$path = "C:\Users\aaron\Projects\Carbon"
$properties = New-Object PsObject -Property #{ 'Path' = $path; 'Files' = 0; 'Folders' = 0; 'Size' = 0 }
Get-ChildItem -Path $path -Recurse |
ForEach-Object {
if( $_.PsIsContainer )
{
$properties.Folders++
}
else
{
$properties.Size += $_.Length
$properties.Files++
}
}
$properties

Related

How to merge two tables that have same table structure? in PowerShell

In the following script, the outputs are displayed as two separate tables (each with two columns). How can I display both tables in a table with three columns?
# Create a hash table for File QTY
$Qty = #{}
# Create a hash table for file size
$Size = #{}
# Import all files into one $Files
$Files = Get-ChildItem 'D:\' -Filter *.* -Recurse -File
# Create a loop to check $file in $Files
foreach ($file in $Files) {
# Count files based on Extension
$Qty[$file.Extension] += 1
# Summarize file sizes based on their format
$Size[$file.Extension] += $file.Length / 1GB
}
# Show File QTY table
$Qty
# Show file size table
$Size
Like this:
Type Size Qyt
----- ----- -----
.jpg 10 GB 10000
.png 30 GB 30000
.tif 40 GB 40000
Extract the keys (the file extensions) from one table and use that as a "driver" to construct a new set of objects with the size and quantity values from the tables:
$Qty.psbase.Keys |Select-Object #{Name='Type';Expression={$_}},#{Name='Size';Expression={$Size[$_]}},#{Name='Qty'; Expression={$Qty[$_]}}
While you already got an answer that does exactly what you asked for, I would take a different approach, that doesn't need hashtables:
# Import all files into one $Files
$Files = Get-ChildItem 'D:\' -Filter *.* -Recurse -File
# Group files by extension and collect the per-extension information
$Files | Group-Object -Property Extension |
Select-Object #{ n = 'Type'; e = 'Name' },
#{ n = 'Size'; e = { '{0:0.00} GB' -f (($_.Group | Measure-Object Length -Sum).Sum / 1GB) } },
#{ n = 'Qty'; e = 'Count' }
Output is like:
Type Size Qty
----- ----- -----
.jpg 10.23 GB 10000
.png 30.07 GB 30000
.tif 40.52 GB 40000
Group-Object produces an object per unique file extension. It has a property Count, which is the number of grouped items, so we can use that directly. Its property Name contains the file extension. Its Group property contains all FileInfo objects from Get-ChildItem that have the same extension.
Using Select-Object we rename the Name property to Type and rename the Count property to Qty. We still need to calculate the total size per file type, which is done using Measure-Object -Sum. Using the format operator -f we pretty-print the result.
Replace {0:0.00} by {0:0} to remove the fractional digits from the Size column.
The syntax #{ n = ...; e = ... } is shortcut for #{ name = ...; expression = ... } to create a calculated property.
You may defer the formatting of the Size column to Format-Table, to be able to do additional processing based on the numeric value, e. g. sorting:
$files | Group-Object -Property Extension |
Select-Object #{ n = 'Type'; e = 'Name' },
#{ n = 'Size'; e = { ($_.Group | Measure-Object Length -Sum).Sum } },
#{ n = 'Qty'; e = 'Count' } |
Sort-Object Size -Descending |
Format-Table 'Type', #{ n = 'Size'; e = { '{0:0} GB' -f ($_.Size / 1GB) } }, 'Qty'

Resolve-Path: cannot find path because it does not exist. error in powershell

Firstly: what My code does it counts the number of duplicate files in a particular path entered by the user.
It does this by first calculating which files have the same length. and from the files that have the same length, it checks which files also have the same hash. And then in the end I am making an object which contains the information that I need to print in a table.
Problem:
In my code,
I am getting an error which I am pretty sure is coming from the Get-FileHash commandlet.
when I ctrl + click on the link that is given in the "At" section of the error, It takes me to the Get-FileHash commandlet utility in powershell
C: >WIndows > system32 > WindowsPowershell > v1.0 > Modules > Microsoft.Powershell.Utility > Microsoft.Powershell.Utility.psm1 > Get-FileHash{}
the error only comes up for some .msg and .pdf files
the code works perfectly fine on a path with lesser files.
Here is the Error:
Resolve-Path : Cannot find path '<path of File>' because it does not exist.
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Utility\Micro
+ ... $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Forea ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (<nameOfFile>:String)
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathComm
And here is the code:
#taking the input of the user!
$pathInputByUser = Read-Host ("Please Enter the Path where you want to check for duplicate files")
#Accessing the path entered by the user
cd $pathInputByUser
write-host ("Loading: Please Wait! This can take a upto 2.5 hrs") -ForegroundColor Green
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew();
$totalNumOfFiles = 0;
#the variable "filesGroupedAccordingToLength" contains all the files grouped according to their size. files with same size , are in the same group
$filesGroupedAccordingToLength = Get-ChildItem -Recurse -File `
| Group-Object -Property Length
#below calculating the number of total Files that we have found till now
$totalNumOfFiles = $filesGroupedAccordingToLength | Measure-Object -Property Count -Sum | % { $_.sum };
#the below variable "filesWhichHaveSameLengths" contains group of files that have the same size as some other file
$filesWhichHaveSameLengths = $filesGroupedAccordingToLength | ? { $_.Count -gt 1 } `
| % { $_.Group }
#the below variable "hash" contains group of files that have the same hash as some other file
$groupedFilesWithSameHash = $filesWhichHaveSameLengths | Get-FileHash `
| Group-Object -Property Hash `
| ? { $_.Count -gt 1 }
$numOfDuplicates= 0;
$calculatingCountDuplicates= $groupedFilesWithSameHash| Select-Object -ExpandProperty Count| %{ $numOfDuplicates= $numOfDuplicates + ($_ - 1) };
"The number of duplicate files are: $numOfDuplicates"
#the below variables contains hash of duplicate files
$hashOfDuplicateFiles= $groupedFilesWithSameHash | % { $_.Group }
#making objects to be able to display result as a table
$res= #();
$hashValue=0;
foreach ($tuple in $hashOfDuplicateFiles) {
foreach ($var in $filesWhichHaveSameLengths) {
if ($var.FullName -eq $tuple.Path) {
$obj= new-object psobject -Property #{
LastWriteTime = $var.LastWriteTime
Name = $var.Name
length = $var.length
FullName = $var.FullName
hash = $tuple.Hash
RelativePath = $var.PSPath.Replace("Microsoft.PowerShell.Core\FileSystem::F:\", "")
}
if($tuple.Hash -ne $hashValue){
$obj|Add-Member -NotePropertyName U/D -NotePropertyValue "Unikat"
$res= $res+$obj;
$hashValue= $tuple.Hash;
}
else{
$obj|Add-Member -NotePropertyName U/D -NotePropertyValue "Duplikat"
$res= $res+$obj;
}
}
}
}
$res | Format-Table -AutoSize -Property Name, U/D, LastWriteTime, hash, length, RelativePath |Out-File -FilePath C:\Users\Public\Documents\Ebrahim_iris\DuplicateFinderTool\testLog.txt
"the number of total files is : $totalNumOfFiles"
"The number of duplicate files are: $numOfDuplicates"
"The number of unique files are: $($totalNumOfFiles-$numOfDuplicates)"
$Stopwatch.Stop();
"The script ran for: $($Stopwatch.Elapsed.TotalMinutes) minutes"
Any advice to remove this error will be appreciated.

Modifying the Powershell calculated property with directory size

I am trying to modify the below script to add one more column 'Directory size' so that it shows the total directory size for NTFS share.
Function Get-SmbSharePermission([String]$ComputerName = '.') {
$Shares = #{}
Get-WmiObject -Class Win32_Share -ComputerName $ComputerName | ForEach-Object {$Shares[$_.Name] = $_.Path}
Get-WmiObject -Class Win32_LogicalShareSecuritySetting -ComputerName $ComputerName | ForEach-Object {
$Name = $_.Name
$_.GetSecurityDescriptor().Descriptor.DACL | Select-Object -Property `
#{n='ComputerName'; e={$ComputerName}},
#{n='Name'; e={$Name}},
#{n='Path'; e={$Shares[$Name]}},
#{n='Account'; e={"$($_.Trustee.Domain)\$($_.Trustee.Name)".Trim('\')}},
#{n='Permission'; e={
Switch ($_.AccessMask) {
0x001F01FF {'Full'}
0x001301BF {'Change'}
0x001200A9 {'Read'}
default {"0x$($_.ToString('X8'))"}
}
}},
#{n='Type'; e={If ($_.AceType) {'Deny'} Else {'Allow'}}}
}
}
Get-SmbSharePermission | ogv
The script above does almost everything, except the total size of the directory.
How can I integrate it with the below function that can show the directory size?
$scriptBlock = {
param ([string]$Path,
[string]$GroupName)
# Get the total directory number and file counts
# the '/L' [for List] tells robocopy to not do anything, just list what it _would_ do
# /E :: copy subdirectories, including Empty ones.
# /L :: List only - don't copy, timestamp or delete any files.
# /NFL :: No File List - don't log file names.
# /NDL :: No Directory List - don't log directory names.
# /NP :: No Progress - don't display percentage copied.
$RC_Results = robocopy $Path 'NULL' /L /E /NP /NFL /NDL
# check to see if i forgot to re-enable the robocopy run [*blush*]
if ($RC_Results.Count -eq 0)
{
Write-Warning "You need to remove the `#` on line 2."
break
}
# the summary table is the first 5 of the last 7 lines
$RC_Summary = $RC_Results |
Select-Object -Last 7 |
Select-Object -First 5
# add a 'Type' column header to the 1st line
$RC_Summary[0] = 'Type' + $RC_Summary[0]
# add placeholders for the blank 'Times' [last line] columns
$RC_Summary[-1] = $RC_Summary[-1].
Insert(39, 'N/A').
Insert(49, 'N/A')
$NewRC_Summary = #()
# line cleanup
foreach ($Line in $RC_Summary)
{
# remove leading and trailing spaces
$NewLine = $Line.Trim()
# remove ':' that are NOT in time spans
$NewLine = $NewLine.Replace(' :', '')
# replace multi-spaces with singletons
$NewLine = $NewLine -replace '\s{2,}', ' '
# remove space between number and unit letter [bytes, kilobytes, etc.]
# 1.22 m >> 1.22m
$NewLine = $NewLine -replace '(\d)\s([bkmg])', '$1$2'
# replace remaining spaces with a comma
$NewLine = $NewLine.Replace(' ', ',')
# add to the new summary collection
$NewRC_Summary += $NewLine
}
$RC_SummaryTable = #{ }
foreach ($Item in ($NewRC_Summary | ConvertFrom-Csv))
{
$RC_SummaryTable.Add($Item.Type, $Item.Total)
}
[PSCustomObject] #{
DirPath = $Path
DirCount = "{0}" -f $RC_SummaryTable['Dirs']
FileCount = "{0}" -f $RC_SummaryTable['Files']
TotalSize = "{0}" -f $RC_SummaryTable['Bytes']
}
}
Update
The suggested code by Cpt. Whale below shows the whole disk drive size not each directories under Path:
I prefer to use volume information rather than doing a complete file listing via robocopy. I'm using the newer CimInstance powershell cmdlets here to get the volume information via Get-SmbShare:
Function Get-SmbSharePermission([String]$ComputerName = '.') {
# Create a cim session to use later, and get a list of the remote share objects:
$cim = New-CimSession -ComputerName $Computername
$shares = Get-SmbShare -CimSession $cim | Where Name -NotIn 'print$','IPC$'
# Iterate through each share
Foreach ($Share in $shares) {
# Skip shares without volume info (not file shares, e.g. shared printers)
if(!$Share.Volume){continue}
# Get the assoviated volume size
$Volume = Get-Volume -CimSession $cim -UniqueId $Share.Volume
# Get the access information, and format
Get-SmbShareAccess -CimSession $cim -Name $Share.Name | Select `
#{n='ComputerName'; e={$ComputerName}},
#{n='Name'; e={$Share.Name}},
#{n='Path'; e={$Share.Path}},
#{n='Account'; e={$_.AccountName}},
#{n='Permission'; e={$_.AccessRight}},
#{n='Type'; e={$_.AccessControlType}},
#{n='Drive'; e={$Volume.DriveLetter}},
#{n='TotalSize'; e={[String][Math]::Round($Volume.Size/1GB)+' GB'}},
#{n='FreeSpace'; e={[String][Math]::Round($Volume.SizeRemaining/1GB)+' GB'}}
}
}
# Output:
Get-SmbSharePermission | ft
ComputerName Name Path Account Permission Type Drive TotalSize FreeSpace
------------ ---- ---- ------- ---------- ---- ----- --------- ---------
RemoteServer ADMIN$ C:\WINDOWS BUILTIN\Administrators Full Allow C 100 GB 20 GB
RemoteServer ADMIN$ C:\WINDOWS BUILTIN\Backup Operators Full Allow C 100 GB 20 GB
RemoteServer ADMIN$ C:\WINDOWS NT AUTHORITY\INTERACTIVE Full Allow C 100 GB 20 GB

PowerShell - Listing all Folders, Subfolders and each contained files (recursive) but in a formatted way (Tree-View)

I use the following commands on PowerShell to create a list of all files and subfolders within a specific directory:
get-childitem -path c:\users\username\desktop\test -recurse | select name
So assuming I have a folder called "test" on my desktop and within this folder I have three files and one subfolder, which itself contains further files and subfolders and so on, I do get something like this as an output:
subfolder 1 of "test"
file 1 in "test"
file 2 in "test"
file 3 in "test"
subfolder a of "subfolder 1"
file 1 in subfolder 1
file 2 in subfolder 1
file 3 in subfolder 1
file 1 in subfolder a
file 2 in subfolder a
file 3 in subfolder a
So this is nice but I would like to get another kind of output, something looking like this:
+ c:\users\username\desktop\test
| - file 1 in "test"
| - file 2 in "test"
| - file 3 in "test"
|--+ subfolder 1 of "test"
| | - file 1 in subfolder 1
| | - file 2 in subfolder 1
| | - file 3 in subfolder 1
| |--+ subfolder a of "subfolder 1"
| | | - file 1 in subfolder a
| | | - file 2 in subfolder a
| | | - file 3 in subfolder a
|--+ subfolder 2 of "test"
| | -
| | .
| . .
. .
.
Is it possible (and if yes - how then?) to get an output looking like this?
I know there was a dos command called "tree" back then but it cannot work with the output of get-childitem in PowerShell due to its limitations. Is there some kind of equivalent command in PowerShell or can I do this with the get-childitem command and its switches / additions / ... ?
Sorry for my bad English.
And: Sorry, I am a total beginner on PowerShell.
The old "Tree" you're used to from cmd is an application in your system32 folder rather than some hard-coded cmd functionality.
So you can still run it from powershell as usual.
e.g.
Tree 'C:\Foldername'
Robocopy and some other well known applications work the same way.
Errors in external programs can be captured in $LastExitCode rather than the usual $Error. What those codes mean will vary depending on the program.
You can call any cmd/DOS executable from Powershell. As long as you do so properly. IN the consolehost (powershell.exe/pwsh.exe), it's virtually the same as using cmd.exe, but from the ISE it's a bit different. YOu can't use interactive commands in the ISE. You can use the command, but you must pass t al it needs.
In the PowerShell consolehost (powershell.exe/pwsh.exe), just type...
$PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.19041.1}
BuildVersion 10.0.19041.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
tree |more
Folder PATH listing for volume Data
Volume serial number is CE3D-F392
D:.
├───.vs
│ └───Scripts
│ └───v16
├───.vscode
...
PowerShell: Running Executables
No reason to start this from scratch. There are plenty of examples and even modules that provide this capability.
A quick search would show you start with a tweak or use as they are...
'PowerShell treeView':
PowerTip: View Directory List as Tree by Using PowerShell
Use the Show-Tree cmdlet from the PowerShell Community Extension Project:
Find-Module -Name pscx |
Format-Table -AutoSize
# Results
<#
Version Name Repository Description
------- ---- ---------- -----------
3.3.2 Pscx PSGallery PowerShell Community Extensions (PSCX) base module which implements a general-purpose set of Cmdlets.
#>
Show-Tree e:\data –depth 2
https://serverfault.com/questions/744660/powershell-populating-treeview-with-directory-hierarchy
$objDriveLetters = GET-WMIOBJECT –query "SELECT * from win32_logicaldisk"
$form = New-Object System.Windows.Forms.Form
$treeView = New-Object System.Windows.Forms.TreeView
$treeView.Dock = 'Fill'
$treeView.CheckBoxes = $true
foreach ($iDrive in $objDriveLetters)
{
$DriveRoot = Get-Item $iDrive.DeviceID
#$FolderRoot = Get-ChildItem -Path $iDrive.DeviceID
$FolderRoot = Get-Item -Path $iDrive.DeviceID
$treeView.Nodes.Add($FolderRoot.FullName, $FolderRoot.FullName)
}
$form.Controls.Add($treeView)
$form.ShowDialog()
Create A File System Size Tree View Using PowerShell:
https://key2consulting.com/powershell-file-directory-tree-view
#Variables that need to be set for each run
$startFolder = "C:\Program Files"; #The starting folder to analyze
$sourceHTMLFile = "C:\finalTemplate.html"; #The html source template file
$destinationHTMLFile = "C:\final.html"; #The final html file that will be produced, #does not need to exist
$htmlLines = #();
#Function that creates a folder detail record
function CreateFolderDetailRecord
{
param([string]$FolderPath)
#Get the total size of the folder by recursively summing its children
$subFolderItems = Get-ChildItem $FolderPath -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
$folderSizeRaw = 0;
$folderSize = 0;
$units = "";
#Account for no children
if($subFolderItems.sum -gt 0)
{
$folderSizeRaw = $subFolderItems.sum;
}
#Determine units for a more friendly output
if(($subFolderItems.sum / 1GB) -ge 1)
{
$units = "GB"
$folderSize = [math]::Round(($subFolderItems.sum / 1GB),2)
}
else
{
if(($subFolderItems.sum / 1MB) -ge 1)
{
$units = "MB"
$folderSize = [math]::Round(($subFolderItems.sum / 1MB),2)
}
else
{
$units = "KB"
$folderSize = [math]::Round(($subFolderItems.sum / 1KB),2)
}
}
#Create an object with the given properties
$newFolderRecord = New-Object –TypeName PSObject
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderPath –Value $FolderPath;
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderSizeRaw –Value $folderSizeRaw
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderSizeInUnits –Value $folderSize;
$newFolderRecord | Add-Member –MemberType NoteProperty –Name Units –Value $units;
return $newFolderRecord;
}
#Function that recursively creates the html for the output, given a starting location
function GetAllFolderDetails
{
param([string]$FolderPath)
$recursiveHTML = #();
#Get properties used for processing
$folderItem = Get-Item -Path $FolderPath
$folderDetails = CreateFolderDetailRecord -FolderPath $FolderPath
$subFolders = Get-ChildItem $FolderPath | Where-Object {$_.PSIsContainer -eq $true} | Sort-Object
#If has subfolders, create hmtl drilldown.
if($subFolders.Count -gt 0)
{
$recursiveHTML += "<li><span class='caret'>" + $folderItem.Name + " (<span style='color:red'>" + $folderDetails.FolderSizeInUnits + " " + $folderDetails.Units + "</span>)" + "</span>"
$recursiveHTML += "<ul class='nested'>"
}
else
{
$recursiveHTML += "<li>" + $folderItem.Name + " (<span style='color:red'>" + $folderDetails.FolderSizeInUnits + " " + $folderDetails.Units + "</span>)";
}
#Recursively call this function for all subfolders
foreach($subFolder in $subFolders)
{
$recursiveHTML += GetAllFolderDetails -FolderPath $subFolder.FullName;
}
#Close up all tags
if($subFolders.Count -gt 0)
{
$recursiveHTML += "</ul>";
}
$recursiveHTML += "</li>";
return $recursiveHTML
}
#Processing Starts Here
#Opening html
$htmlLines += "<ul id='myUL'>"
#This function call will return all of the recursive html for the startign folder and below
$htmlLines += GetAllFolderDetails -FolderPath $startFolder
#Closing html
$htmlLines += "</ul>"
#Get the html template, replace the template with generated code and write to the final html file
$sourceHTML = Get-Content -Path $sourceHTMLFile;
$destinationHTML = $sourceHTML.Replace("[FinalHTML]", $htmlLines);
$destinationHTML | Set-Content $destinationHTMLFile

How to convert string to integer in PowerShell

I have a list of directories with numbers. I have to find the highest number and and increment it by 1 and create a new directory with that increment value. I am able to sort the below array, but I am not able to increment the last element as it is a string.
How do I convert this below array element to an integer?
PS C:\Users\Suman\Desktop> $FileList
Name
----
11
2
1
You can specify the type of a variable before it to force its type. It's called (dynamic) casting (more information is here):
$string = "1654"
$integer = [int]$string
$string + 1
# Outputs 16541
$integer + 1
# Outputs 1655
As an example, the following snippet adds, to each object in $fileList, an IntVal property with the integer value of the Name property, then sorts $fileList on this new property (the default is ascending), takes the last (highest IntVal) object's IntVal value, increments it and finally creates a folder named after it:
# For testing purposes
#$fileList = #([PSCustomObject]#{ Name = "11" }, [PSCustomObject]#{ Name = "2" }, [PSCustomObject]#{ Name = "1" })
# OR
#$fileList = New-Object -TypeName System.Collections.ArrayList
#$fileList.AddRange(#([PSCustomObject]#{ Name = "11" }, [PSCustomObject]#{ Name = "2" }, [PSCustomObject]#{ Name = "1" })) | Out-Null
$highest = $fileList |
Select-Object *, #{ n = "IntVal"; e = { [int]($_.Name) } } |
Sort-Object IntVal |
Select-Object -Last 1
$newName = $highest.IntVal + 1
New-Item $newName -ItemType Directory
Sort-Object IntVal is not needed so you can remove it if you prefer.
[int]::MaxValue = 2147483647 so you need to use the [long] type beyond this value ([long]::MaxValue = 9223372036854775807).
Example:
2.032 MB (2,131,022 bytes)
$u=($mbox.TotalItemSize.value).tostring()
$u=$u.trimend(" bytes)") #yields 2.032 MB (2,131,022
$u=$u.Split("(") #yields `$u[1]` as 2,131,022
$uI=[int]$u[1]
The result is 2131022 in integer form.
Use:
$filelist = #(11, 1, 2)
$filelist | sort #{expression={$_[0]}} |
% {$newName = [string]([int]$($_[0]) + 1)}
New-Item $newName -ItemType Directory
Use:
$filelist = #("11", "1", "2")
$filelist | sort #{expression={[int]$_}} | % {$newName = [string]([int]$_ + 1)}
New-Item $newName -ItemType Directory
If someone is looking for how this can be run from command line, as a single command, this is one way it can be done:
$FileList | ` # Writes array to pipeline
Select-Object -Last 1 | ` # Selects last item in array
ConvertFrom-String -TemplateContent "{[int]NameTmp:12}" | ` # Converts string to number and names the variable "NameTmp"
Add-Member -Name "Name" -Value { $this.NameTmp + 1 } -MemberType ScriptProperty -PassThru | ` # Increments variable "NameTmp" by one and adds new variable named "Name" to pipeline object
New-Item -Type Directory # Creates new directy in current folder. Takes directory name from pipelined "Name" variable
Once you have selected the highest value, which is "12" in my example, you can then declare it as integer and increment your value:
$FileList = "1", "2", "11"
$foldername = [int]$FileList[2] + 1
$foldername