Dictionaries/Computer.Dict.Windows/Computer.Dict.Windows.psm1
<#
###### ####### ## ## ######## ## ## ######## ######## ######## ## ## ## ## ### ### ## ## ## ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ## ## ## ## ## ### ## ######## ## ## ## ###### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ####### ## ## ## ####### ## ######## ## ## #> # function Get-MyInvocation { # [CmdletBinding()] # [OutputType([String])] # Param ( # ) # Begin { # Write-EnterFunction # } # Process { # $MyInvocation # } # End { # Write-LeaveFunction # } # } <# .SYNOPSIS Get the computer name .DESCRIPTION .EXAMPLE $name = Get-ComputerName .NOTES This function comes from Dict.Windows module. #> function Get-ComputerName { [CmdletBinding()]Param ( ) Begin { Write-EnterFunction } Process { return (hostname) -replace "\..*" } End { Write-LeaveFunction } } <# .SYNOPSIS Get the computer DNS domain name .DESCRIPTION .PARAMETER localhost request localhost's DNS domain .EXAMPLE $name = Get-ComputerDomain .NOTES This function comes from Dict.Windows module. #> function Get-ComputerDomain { [CmdletBinding()][OutputType([String])]Param ( ) Begin { Write-EnterFunction } Process { if (fileExist "Env:\USERDNSDOMAIN") { return $env:USERDNSDOMAIN } return 'localdomain' } End { Write-LeaveFunction } } <# .SYNOPSIS Get the computer SerialNumber .DESCRIPTION .PARAMETER localhost request localhost's SerialNumber .EXAMPLE $name = Get-ComputerSerialNumber .NOTES This function comes from Dict.Windows module. #> function Get-ComputerSerialNumber { [CmdletBinding()]Param ( ) Begin { Write-EnterFunction } Process { return (Get-CimInstance -ClassName Win32_BIOS).SerialNumber } End { Write-LeaveFunction } } <# .SYNOPSIS Get the computer manufacturer .DESCRIPTION .PARAMETER localhost request localhost's manufacturer .EXAMPLE $name = Get-ComputerManufacturer .NOTES This function comes from Dict.Windows module. #> function Get-ComputerManufacturer { [CmdletBinding()]Param ( ) Begin { Write-EnterFunction } Process { return (Get-CimInstance -ClassName Win32_BIOS).Manufacturer } End { Write-LeaveFunction } } <# .SYNOPSIS Get the computer Version .DESCRIPTION .PARAMETER localhost request localhost's Version .EXAMPLE $name = Get-ComputerVersion .NOTES This function comes from Dict.Windows module. #> function Get-ComputerVersion { [CmdletBinding()]Param ( ) Begin { Write-EnterFunction } Process { return (Get-CimInstance -ClassName Win32_BIOS).SMBIOSBIOSVersion } End { Write-LeaveFunction } } <# .SYNOPSIS Get the computer Model .DESCRIPTION .PARAMETER localhost request localhost's Model .EXAMPLE $name = Get-ComputerModel .NOTES This function comes from Dict.Windows module. #> function Get-ComputerModel { [CmdletBinding()]Param ( ) Begin { Write-EnterFunction } Process { # deprecated in Powershell Core # return (Get-WmiObject -Class:Win32_ComputerSystem).Model return (Get-CimInstance -ClassName Win32_ComputerSystem).Model } End { Write-LeaveFunction } } function Get-ComputerEthernet { [CmdletBinding()]Param ( [switch]$localhost, [ValidateSet('Index', 'Name')] [string]$ListAvailable = 'Index' ) Begin { Write-EnterFunction } Process { switch ($ListAvailable) { 'Index' { (Get-NetAdapter -Physical).ifIndex | Sort-Object # (Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration).Index | Sort-Object } 'Name' { # (Get-NetAdapter -IncludeHidden).Name | Sort-Object (Get-NetAdapter -Physical).Name | Sort-Object } } } End { Write-LeaveFunction } } <# .Synopsis Determines underlying firmware (BIOS) type and returns an integer indicating UEFI, Legacy BIOS or Unknown. Supported on Windows 8/Server 2012 or later .DESCRIPTION This function uses a complied Win32 API call to determine the underlying system firmware type. .EXAMPLE If (Get-ComputerFirmwareType -eq "UEFI") { # System is running UEFI firmware... } .EXAMPLE Switch (Get-ComputerFirmwareType) { "BIOS" { "Legacy BIOS" } "UEFI" { "UEFI" } Default { "Unknown" } } .OUTPUTS string "BIOS" or "UEFI" .FUNCTIONALITY Determines underlying system firmware type .LINK https://gallery.technet.microsoft.com/scriptcenter/Determine-UEFI-or-Legacy-7dc79488 .NOTES Author : Chris J Warwick https://social.technet.microsoft.com/profile/chris%20j%20warwick/ #> function Get-ComputerFirmwareType { [CmdletBinding()][OutputType([String])]Param ( # [switch]$localhost, # [string]$string = "" ) Begin { # eenter($MyInvocation.MyCommand) } Process { Add-Type -Language CSharp -TypeDefinition @' using System; using System.Runtime.InteropServices; public class FirmwareType { [DllImport("kernel32.dll")] static extern bool GetFirmwareType(ref uint FirmwareType); public static uint GetFirmwareType() { uint firmwaretype = 0; if (GetFirmwareType(ref firmwaretype)) return firmwaretype; else return 0; // API call failed, just return 'unknown' } } '@ $fw = "BIOS" $firmwareTypeNum = [FirmwareType]::GetFirmwareType() Switch ($firmwareTypeNum) { 1 { $fw = "BIOS" } 2 { $fw = "UEFI" } Default { $fw = "Unknown ($firmwareTypeNum)" } } return $fw } End { # eleave($MyInvocation.MyCommand) } } function Get-ComputerArch { [CmdletBinding()][OutputType([String])]Param ( [switch]$localhost, [string]$string = "" ) Begin { # eenter($MyInvocation.MyCommand) } Process { # found specs @url https://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx $value = (Get-CimInstance -ClassName CIM_Processor).DataWidth switch ($value) { 32 { return 'x86' } 64 { return 'x64' } else { return 'unknown' } } } End { # eleave($MyInvocation.MyCommand) } } <# ######## ######## ## ## ######## ######## ## ## ######## ######## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ###### ## ######### ###### ######## ## ## ## ###### ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ### ## ## ######## ## ## ## ######## ## ## ## ## ######## ## #> # Get-NetAdapter is not available under all versions of Windows # array of interfaces found $Script:interfaces = @() <# .SYNOPSIS Gather informations about network interfaces from registry. .DESCRIPTION Get-NetAdapter is not available under all versions of Windows. That's why we try to gather informations from the registry. .EXAMPLE $interfaces = Get-ComputerNetAdapter .NOTES General notes #> function Get-ComputerNetAdapter { [CmdletBinding()] [OutputType([array])] Param ( # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string # [switch]$Passthru, # Force a refresh, do not blindly return cache [Alias('Refresh')] [switch]$Force ) Begin { Write-EnterFunction } Process { if (($null -eq $Script:interfaces) -or $Force) { $Script:interfaces = @() $TcpipRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces" $NetsetupRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\NetworkSetup2\Interfaces" foreach ($item in (Get-ChildItem $TcpipRegPath | Where-Object { $_.PSIsContainer -eq $true })) { $interface = @{} $interface.guid = $item.PSChildName foreach ($property in (Get-Item $item).property) { $interface.$property = Get-ItemPropertyValue $item -name $property } foreach ($property in (Get-Item "$NetsetupRegPath\$($item.PSChildName)\Kernel").property) { $interface.$property = Get-ItemPropertyValue "$NetsetupRegPath\$($item.PSChildName)\Kernel" -name $property } $Script:interfaces += $interface } } return $Script:interfaces } End { Write-LeaveFunction } } function Get-EthIndex { [CmdletBinding()]Param( [Parameter(ValueFromPipeLine = $true)] [string]$AdapterName = "", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { # switch ($Family) { # 'IPv4' { # $inet = "inet" # } # 'IPv6' { # $inet = "inet6" # } # } $value = (Get-NetAdapter -Name $AdapterName).ifIndex return $value } End { Write-LeaveFunction } } function Get-EthName { [CmdletBinding()]Param( [Parameter(ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { # switch ($Family) { # 'IPv4' { # $inet = "inet" # } # 'IPv6' { # $inet = "inet6" # } # } $value = (Get-NetAdapter -InterfaceIndex $AdapterIndex).Name return $value } End { Write-LeaveFunction } } function Get-EthLinkStatus { [CmdletBinding( DefaultParameterSetName="INDEX" )][OutputType([Boolean])]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 1, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo" ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { $AdapterName = Get-EthName -AdapterIndex $AdapterIndex } 'NAME' { } } $status = (Get-NetAdapter -Name $AdapterName).Status switch ($status) { 'Up' { return $true } default { return $false } } } End { Write-LeaveFunction } } <# .SYNOPSIS Get network adapter speed .DESCRIPTION Ask OS for network adapter speed .PARAMETER AdapterIndex Adapter index .PARAMETER AdapterName Adapter name .EXAMPLE Get-EthSpeed -AdapterIndex 0 .EXAMPLE Get-EthSpeed -AdapterName Ethernet0 .OUTPUTS [uint32] return link speed in bytes per seconds .NOTES General notes #> function Get-EthSpeed { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo" ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { $AdapterName = Get-EthName -AdapterIndex $AdapterIndex } 'NAME' { } } [uint32]$value = (Get-NetAdapter -name $AdapterName).Speed return $value } End { Write-LeaveFunction } } function Get-EthMacAddress { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { # switch ($Family) { # 'IPv4' { # $inet = "inet" # } # 'IPv6' { # $inet = "inet6" # } # } switch ($PSCmdlet.ParameterSetName) { 'INDEX' { $AdapterName = Get-EthName -AdapterIndex $AdapterIndex } 'NAME' { } } $value = (Get-NetAdapter -name $AdapterName).MacAddress.ToLower().Replace('-',':') return $value } End { Write-LeaveFunction } } function Get-EthIPAddress { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { } 'NAME' { $AdapterIndex = Get-EthIndex -AdapterName $AdapterName } } try { $value = (Get-NetIPaddress -InterfaceIndex $AdapterIndex -AddressFamily $Family -ErrorAction:SilentlyContinue).IPAddress } catch { $value = [ipaddress]"0.0.0.0" } return $value } End { Write-LeaveFunction } } function Get-EthNetMask { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { } 'NAME' { $AdapterIndex = Get-EthIndex -AdapterName $AdapterName } } switch ($Family) { 'IPv4' { try { $mask = (Get-NetIPConfiguration -InterfaceIndex $AdapterIndex).ipv4address.prefixlength $value = ConvertTo-Mask -MaskLength $mask } catch { $value = [ipaddress]"255.255.255.255" } } 'IPv6' { # $mask = (Get-NetIPConfiguration -InterfaceIndex $AdapterIndex).ipv6address.prefixlength ewarn("Module Indented.Net.IP does not provides IPv6 calculator yet !!") } } return $value } End { Write-LeaveFunction } } function Get-EthBroadcast { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { } 'NAME' { $AdapterIndex = Get-EthIndex -AdapterName $AdapterName } } $ip = Get-EthIPAddress -AdapterIndex $AdapterIndex -Family $Family $mask = Get-EthNetMask -AdapterIndex $AdapterIndex -Family $Family switch ($Family) { 'IPv4' { $value = Get-BroadcastAddress -IPAddress $ip -SubnetMask $mask } 'IPv6' { ewarn("Module Indented.Net.IP does not provides IPv6 calculator yet !!") } } return $value } End { Write-LeaveFunction } } function Get-EthGateway { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( # Parameter help description [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$AdapterIndex = 0, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$AdapterName = "lo", [ValidateSet('IPv4', 'IPv6')] [string]$Family = 'IPv4' ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { } 'NAME' { $AdapterIndex = Get-EthIndex -AdapterName $AdapterName } } switch ($Family) { 'IPv4' { try { $value = (get-netroute -ifIndex $AdapterIndex -DestinationPrefix 0.0.0.0/0).NextHop } catch { $value = [ipaddress]"0.0.0.0" } } 'IPv6' { $value = [ipaddress]"0.0.0.0" # $value = (get-netroute -ifIndex $AdapterIndex -DestinationPrefix 0.0.0.0/0).NextHop } } return $value } End { Write-LeaveFunction } } function Get-ComputerDisks { [CmdletBinding()]Param ( [switch]$localhost, [ValidateSet('Index', 'Name')] [string]$ListAvailable = 'Index' ) Begin { Write-EnterFunction $precedence = @('Fixed') } Process { if ($Localhost) { foreach ($p in $precedence) { switch ($ListAvailable) { 'Index' { (Get-Disk | Where-Object { $_.ProvisioningType -eq $p }).Number } 'Name' { (Get-Disk | Where-Object { $_.ProvisioningType -eq $p }).UniqeId } } } } } End { Write-LeaveFunction } } function Get-ComputerDisks2 { [CmdletBinding( DefaultParameterSetName="ALL" )]Param( [switch]$localhost, [ValidateSet('Index', 'Name')] [string]$ListAvailable = 'Index', [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$Index, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$Name ) Begin { $disks = @() # precedence tell the order search precedence of the type of disk. It aims to mimic BIOS / UEFI discovery order $list = Get-Disk } Process { ForEach ($hash in $list) { $disk = $null # $disk = [PSCustomObject]@{ # Index = $i++ # Name = $d # serial = $lsblk.serial # uuid = $lsblk.uuid # manufacturer = $lsblk.vendor # model = $lsblk.model # PhysicalSectorSize = $lsblk."phy-sec" # size = ($lsblk.size.replace(',','.') + "B")/1 | Convert-Size -From Bytes -To Bytes -Precision 0 # PartitionStyle = "" # DriveType = "" # } $disk = @{} $disk.Index = $hash.Number $disk.name = $hash.FriendlyName $disk.serial = $hash.SerialNumber $disk.uuid = $hash.uuid $disk.manufacturer = $hash.Manufacturer $disk.model = $hash.Model $disk.PhysicalSectorSize = $hash.PhysicalSectorSize $disk.size = $hash.size | Convert-Size -From Bytes -To Bytes -Precision 0 $disk.PartitionStyle = $hash.PartitionStyle $disk.DriveType = "" switch ($hash.ProvisioningType) { 'Fixed' { $disk.DriveType = 'Fixed' } 'Removable' { $disk.DriveType = 'Removable' } } $disks += $disk } switch ($PSCmdlet.ParameterSetName) { 'INDEX' { return $disks[$Index] } 'NAME' { $Index = ($disks | Where-Object { $_.Name -eq $Name }).Index if ($null -ne $Index) { return $disks[$Index] } else { return } } 'ALL' { return $disks } } } End { } } <# ######## #### ###### ## ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ##### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## #### ###### ## ## ###### #> function Get-DiskInfos { [CmdletBinding( DefaultParameterSetName="INDEX" )]Param( [switch]$localhost, [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)] [int]$DiskIndex, [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)] [string]$DiskName ) Begin { # eenter($MyInvocation.MyCommand) } Process { switch ($PSCmdlet.ParameterSetName) { 'INDEX' { } 'NAME' { $DiskIndex = (Get-Disk | Where-Object { $_.UniqueId -eq $DiskName }).Number } } $disk = Get-Disk -Number $DiskIndex $obj = [PSCustomObject]@{ name = $disk.UniquId device = $disk.Path index = $disk.Number serial = $disk.SerialNumber uuid = $disk.Guid manufacturer = $disk.Manufacturer model = $disk.Model PhysicalSectorSize = $disk.PhysicalSectorSize default = $disk.IsBoot size = $disk.size PartitionStyle = $disk.PartitionStyle DriveType = $disk.ProvisioningType } return $obj } End { # eleave($MyInvocation.MyCommand) } } <# .SYNOPSIS List local disks .DESCRIPTION Fetch all informations available about local disks. .EXAMPLE An example .NOTES General notes #> function Get-ComputerDisk { [CmdletBinding(DefaultParameterSetName = "ALL")] [OutputType([hashtable])] Param ( # Disk number [Parameter(Mandatory = $true, ParameterSetName = 'DISKNUMBER')][string]$DiskNumber, # Disk device name (without /dev) [Parameter(Mandatory = $true, ParameterSetName = 'DISKNAME')][string]$DiskName, # Full device address like in '/dev/sda1' [Parameter(Mandatory = $true, ParameterSetName = 'DEVICE')][string]$Device, # Partition of the disk given its ID [Alias('UniqueId')] [Parameter(Mandatory = $true, ParameterSetName = 'DISKID')][string]$DiskId, # Return all $disks [Parameter(Mandatory = $false, ParameterSetName = 'ALL')][switch]$All ) Begin { Write-EnterFunction $disks = Get-Disk } Process { switch ($PSCmdlet.ParameterSetName) { 'DISKNUMBER' { $disks = $disks | Where-Object { $_.DiskNumber -eq $DiskNumber } } 'DISKNAME' { $disks = $disks | Where-Object { $_.FriendlyName -eq $DiskName } } 'DEVICE' { $disks = $disks | Where-Object { $_.path -eq $Device } } 'DISKID' { $disks = $disks | Where-Object { $_.UniqueId -eq $DiskId } } default { } } return $disks } End { Write-LeaveFunction } } <# .SYNOPSIS List local partitions .DESCRIPTION Fetch all informations available about local partitions. Linux lacks the 'Get-Partition' of the Storage module available on Windows. .EXAMPLE An example .NOTES General notes #> function Get-ComputerDiskPartition { [CmdletBinding(DefaultParameterSetName = "ALL")] [OutputType([hashtable])] Param ( # Partition object [Parameter(Mandatory = $true, ValueFromPipeLine = $true, ParameterSetName = 'OBJECT')]$InputObject, # Partition with UUID [Alias('UniqueId')] [Parameter(Mandatory = $true, ParameterSetName = 'PARTUUID')][string]$PartUUID, # Label of the partition to mount [Alias('Label', 'PartitionLabel')] [Parameter(Mandatory = $true, ParameterSetName = 'PARTLABEL')][string]$PartLabel, # Disk device name of the partition [Parameter(Mandatory = $true, ParameterSetName = 'DISKPART')][uint32]$DiskNumber, # Partition number (can be several strings char since nvme disks. e.g. 'p1') [Alias('PartNum')] [Parameter(Mandatory = $false, ParameterSetName = 'DISKPART')][uint32]$PartitionNumber, # Full device address like in '/dev/sda1' [Alias('Path')] [Parameter(Mandatory = $true, ParameterSetName = 'DEVICE')][string]$Device, # Mountpoint of a mounted partition [Alias('DriveLetter')] [Parameter(Mandatory = $true, ParameterSetName = 'MOUNTPOINT')][string]$Mountpoint, # Partition of the disk given its ID [Parameter(Mandatory = $true, ParameterSetName = 'DISKID')][string]$DiskId, # Return all partitions [Parameter(Mandatory = $false, ParameterSetName = 'ALL')][switch]$All ) Begin { Write-EnterFunction # $disks = Get-ComputerDisk } Process { switch ($PSCmdlet.ParameterSetName) { 'OBJECT' { $partitions = Get-Partition -DiskNumber $InputObject.DiskNumber -PartitionNumber $InputObject.PartitionNumber } 'PARTUUID' { $partitions = Get-Partition -UniqueId "$PartUUID" } 'PARTLABEL' { $partitions = Get-Partition -Volume (Get-Volume | Where-Object { $_.FileSystemLabel -eq "$Partlabel" }) } 'DISKPART' { if ($PartitionNumber) { $partitions = Get-Partition -DiskNumber $DiskNumber -PartitionNumber $PartitionNumber } else { $partitions = Get-Partition -DiskNumber $DiskNumber } } # 'DEVICE' { # $partitions = ($disks.children | Where-Object { $_.path -like "$Device*" }) # } 'MOUNTPOINT' { # $partitions = Get-Partition -DriveLetter "$Mountpoint" $partitions = (Get-Partition | Where-Object { $Mountpoint -in $_.AccessPaths }) } 'DISKID' { $partitions = Get-Partition -DiskId "$DiskId" } default { $partitions = Get-Partition } } # comply with linux code $parts = @() foreach ($p in $partitions) { # Write-Devel "Processing partition $($p.DiskNumber):$($p.PartitionNumber)" $part = @{} # merge volume information to get partition label for example $vol = get-volume -partition $p # Write-Devel "Found volume $($vol.filesystemlabel)" if ($vol) { $part = Merge-Hashtables ($p | ConvertTo-Hashtable) ($vol | ConvertTo-Hashtable) } if ($part.DriveLetter) { $part.Mountpoint = "$($part.DriveLetter):" } if ($part.AccessPaths) { $part.Mountpoints = $part.AccessPaths } if ("Guid" -notin $part.PSObject.Properties.Name) { $part.Guid = $null } if ($null -eq $part.Guid) { $guid = (New-GUID).Guid try { $part.Guid = $guid } catch { Write-Warning "Partition 'Guid' property cannot be set (readonly ?)."} $part.UUID = $guid } $part.label = $part.FileSystemLabel $parts += $part } # # comply with linux code # for ($i = 0; $i -lt $partitions.count; $i++) { # # merge volume information to get partition label for example # $vol = get-volume -partition $partitions[$i] # if ($vol) { $partitions[$i] | Merge-Object $vol } # if ($partitions[$i].DriveLetter) { $partitions.Mountpoint = "$($partitions[$i].DriveLetter):" } # if ($partitions[$i].AccessPaths) { $partitions.Mountpoints = $partitions[$i].AccessPaths } # if ($null -eq $partitions[$i].Guid) { $partitions.Guid = (New-GUID).Guid } # } return $parts } End { Write-LeaveFunction } } <# .SYNOPSIS Find next available drive DriveLetter .DESCRIPTION List all drive letter already used and return the next one. It does not fill holes, it return the next letter of the far most one used. So if C: D: and G: are used, it will return H:, not E: .EXAMPLE Get-ComputerDiskNextAvailableDriveLetter .NOTES General notes #> function Get-ComputerDiskNextAvailableDriveLetter { [CmdletBinding()] [OutputType([char])] Param ( # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string ) Begin { Write-EnterFunction } Process { # one-liner return [char](([byte]((Get-Volume).DriveLetter | Sort-Object)[-1])+1) } End { Write-LeaveFunction } } <# .SYNOPSIS Mount a partition into running operating system .DESCRIPTION Mount specified partition .EXAMPLE An example .NOTES General notes .OUTPUTS [string] mountpoint #> function Mount-ComputerDiskPartition { [CmdletBinding()] [OutputType([String])] Param ( # Partition object [Parameter(Mandatory = $true, ValueFromPipeLine = $true, ParameterSetName = 'OBJECT')]$InputObject, # UUID of the partition to mount [Parameter(Mandatory = $true, ParameterSetName = 'PARTUUID')][string]$PartUuid, # Label of the partition to mount [Alias('Label', 'PartitionLabel')] [Parameter(Mandatory = $true, ParameterSetName = 'PARTLABEL')][string]$PartLabel, # Disk device name of the partition [Parameter(Mandatory = $true, ParameterSetName = 'DISKPART')][uint32]$DiskNumber, # Partition number (can be several strings char since nvme disks. e.g. 'p1') [Alias('PartNum')] [Parameter(Mandatory = $true, ParameterSetName = 'DISKPART')][uint32]$PartitionNumber, # Full device address like in '/dev/sda1' [Parameter(Mandatory = $true, ParameterSetName = 'DEVICE')][string]$Device, # options to pass [Parameter(Mandatory = $false)][string]$Options, # Unused here. For linux comatibility of Mount-ComputerDiskPartition [Parameter(Mandatory = $false)][switch]$Recurse, # force mounting to the mountpoint [Parameter(Mandatory = $false)][string]$Mountpoint, # Force mounting # If partition is already mounted, it will mount it to another mountpoint [Parameter(Mandatory = $false)][switch]$Force, # if specified, return the whole partition object, # else return only mountpoint [switch]$Passthru ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'OBJECT' { $partition = $InputObject } 'PARTUUID' { $partition = Get-ComputerDiskPartition -PartUUID $PartUuid } 'PARTLABEL' { $partition = Get-ComputerDiskPartition -PartLabel $PartLabel } 'DISKPART' { $partition = Get-ComputerDiskPartition -DiskNumber $DiskNumber -PartitionNumber $PartitionNumber } 'DEVICE' { $partition = Get-ComputerDiskPartition -Device $Device } } # handle -Bind first because if it already mounted we do not have to remount it twice if ($Force) { $Mountpoint = "$($env:ProgramData)\PwSh.Fw.Computer\Mountpoints\$($partition.Guid)\" $partition = Mount-ComputerDiskPartition -InputObject $partition -Mountpoint $Mountpoint -Passthru } # partition is already mounted ? return mountpoint # 1st case -> $Mountpoint not specified and Partition already mounted -> return # 2nd case -> $Mountpoit specified and partition already mounted -> check if partition is mounted on this specific mountpoit if ((!$Mountpoint) -and $partition.mountpoint) { Write-Debug "Partition $($partition.name) already mounted at '$Mountpoint'" if ($Passthru) { return Get-ComputerDiskPartition -InputObject $partition } else { return $Mountpoint } } if ($Mountpoint -in $partition.mountpoints) { Write-Debug "Partition at Disk $($partition.DiskNumber) Partition $($partition.PartitionNumber) already mounted at '$Mountpoint'" if ($Passthru) { return Get-ComputerDiskPartition -InputObject $partition } else { return $Mountpoint } } if (!$Mountpoint) { $Mountpoint = "$($env:ProgramData)\PwSh.Fw.Computer\Mountpoints\$($partition.Guid)" } # auto add ":" char to single drive letter if ($Mountpoint.length -eq 1) { $Mountpoint += ":" } try { $null = New-Item $Mountpoint -ItemType Directory -Force -ErrorAction SilentlyContinue Write-Devel "Add-PartitionAccessPath -DiskNumber $($partition.DiskNumber) -PartitionNumber $($partition.PartitionNumber) -AccessPath $Mountpoint" $null = Add-PartitionAccessPath -DiskNumber $partition.DiskNumber -PartitionNumber $partition.PartitionNumber -AccessPath $Mountpoint } catch { Write-Error $_ } if ($Passthru) { return Get-ComputerDiskPartition -InputObject $partition } else { return $Mountpoint } } End { Write-LeaveFunction } } <# .SYNOPSIS Mount a partition into running operating system .DESCRIPTION Mount specified partition .EXAMPLE An example .NOTES General notes .OUTPUTS [string] mountpoint #> function DisMount-ComputerDiskPartition { [CmdletBinding(DefaultParameterSetName = 'OBJECT')] [OutputType([System.Boolean])] Param ( # Partition object [Parameter(Mandatory = $true, ValueFromPipeLine = $true, ParameterSetName = 'OBJECT')] [object]$InputObject, # UUID of the partition to mount [Parameter(Mandatory = $true, ParameterSetName = 'PARTUUID')][string]$PartUuid, # Label of the partition to mount [Alias('Label', 'PartitionLabel')] [Parameter(Mandatory = $true, ParameterSetName = 'PARTLABEL')][string]$PartLabel, # Disk device name of the partition [Parameter(Mandatory = $true, ParameterSetName = 'DISKPART')][uint32]$DiskNumber, # Partition number (can be several strings char since nvme disks. e.g. 'p1') [Parameter(Mandatory = $true, ParameterSetName = 'DISKPART')][uint32]$PartitionNumber, # Full device address like in '/dev/sda1' [Parameter(Mandatory = $true, ParameterSetName = 'DEVICE')][string]$Device, # Mountpoint of a mounted partition [Alias('DriveLetter')] [Parameter(Mandatory = $false, ParameterSetName = 'OBJECT')] [Parameter(Mandatory = $true, ParameterSetName = 'MOUNTPOINT')] [string]$Mountpoint, # if specified, return the whole partition object, # else return only mountpoint [switch]$Passthru ) Begin { Write-EnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'OBJECT' { $partition = $InputObject } 'PARTUUID' { $partition = Get-ComputerDiskPartition -PartUUID $PartUuid } 'PARTLABEL' { $partition = Get-ComputerDiskPartition -PartLabel $PartLabel } 'DISKPART' { $partition = Get-ComputerDiskPartition -Disk $Disk -PartNum $PartNum } 'MOUNTPOINT' { $partition = Get-ComputerDiskPartition -Mountpoint "$Mountpoint" } 'DEVICE' { $partition = Get-ComputerDiskPartition -Device $Device } } try { if (!$Mountpoint) { $Mountpoint = $partition.AccessPaths[-1] } $p = Remove-PartitionAccessPath -DiskNumber $partition.DiskNumber -PartitionNumber $partition.PartitionNumber -AccessPath $Mountpoint # if successful, remove folder $folder = Get-Item $Mountpoint -ErrorAction SilentlyContinue if ($folder.LinkType) { # folder is not a regular directory. Do not delete it } else { $null = Remove-Item $folder -Force } } catch { Write-Error $_ } $rc = $? if ($Passthru) { return $p } else { return $rc } } End { Write-LeaveFunction } } |