Powershell Debug Output - debugging

I have a powershell script that creates some DotNetZip ZIP files on a persistent connection on multiple servers, then uses Start-BitsTransfer to move the ZIP files from the remote servers to the local.
I run pretty much the same script on two different servers, on one it barely prints anything to the screen. On the other, it outputs a LOT - binary looking stuff. Is this because there is some kind of debug setting that is turned on on the server that is outputting all of this info? Is there a way I can turn it off? I'd rather it be more clean like the first server that runs the script.
Thank you!
-Jim
Here is almost the entire script (without my servernames in the $webServers array:
Import-Module BitsTransfer
foreach($i in $webServers) {
if (!(Test-Path -path \\$i\d$\newDeploy)) {
New-Item \\$i\d$\newDeploy -type directory
}
if (!(Test-Path -path \\$i\d$\newDeploy\backup)) {
New-Item \\$i\d$\newDeploy\backup -type directory
}
if(!(Test-Path \\$i\d$\newDeploy\Ionic.Zip.dll)) {
Start-BitsTransfer -Source \\$webDeployServer\d$\newDeploy\Ionic.Zip.dll -Destination \\$i\d$\newDeploy
}
}
foreach($i in $webServers) {
$sessionForI = New-PSSession -computername $i
Invoke-Command -Session $sessionForI -ScriptBlock {
if ((Test-Path D:\\newDeploy\\backup\\OffM.zip)) {
Remove-Item D:\\newDeploy\\backup\\OffM.zip
}
[System.Reflection.Assembly]::LoadFrom("D:\\newDeploy\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\OffM", "OffM",1)
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\PaEnterprise", "PaEnterprise",1)
$zipfile.Save("D:\\newDeploy\\backup\\OffM.zip")
$zipfile.Dispose()
if ((Test-Path D:\\newDeploy\\backup\\Others.zip)) {
Remove-Item D:\\newDeploy\\backup\\Others.zip
}
[System.Reflection.Assembly]::LoadFrom("D:\\newDeploy\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\MstrInt-PO", "MstrInt-PO",1)
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\Maint", "Maint",1)
$zipfile.Save("D:\\newDeploy\\backup\\Others.zip")
$zipfile.Dispose()
if ((Test-Path D:\\newDeploy\\backup\\PPO.zip)) {
Remove-Item D:\\newDeploy\\backup\\PPO.zip
}
[System.Reflection.Assembly]::LoadFrom("D:\\newDeploy\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\HC", "HC",1)
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\PaOn", "PaOn",1)
if($i -eq 'PYRALNWSP02V') {
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\HearPl", "HearPl",1)
} else {
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\HearPaPlu", "HearPaPlu",1)
}
$zipfile.Save("D:\\newDeploy\\backup\\PPO.zip")
$zipfile.Dispose()
if ((Test-Path D:\\newDeploy\\backup\\TiMan.zip)) {
Remove-Item D:\\newDeploy\\backup\\TiMan.zip
}
[System.Reflection.Assembly]::LoadFrom("D:\\newDeploy\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\TiManView", "TiManView",1)
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\TiManOnline", "TiManOnline",1)
$e = $zipfile.AddSelectedFiles("name != '*.e2e'","D:\inetpub\wwwroot\TiManPOne", "TiManPOne",1)
$zipfile.Save("D:\\newDeploy\\backup\\TiMan.zip")
$zipfile.Dispose()
}
remove-PSSession -session $sessionForI
}
foreach($i in $webServers) {
if(!(Test-Path -path D:\newDeploy\backup\$i)) {
New-Item D:\newDeploy\backup\$i -type directory
}
Start-BitsTransfer -Source \\$i\d$\newDeploy\backup\OffM.zip -Destination D:\newDeploy\backup\$i
Start-BitsTransfer -Source \\$i\d$\newDeploy\backup\Others.zip -Destination D:\newDeploy\backup\$i
Start-BitsTransfer -Source \\$i\d$\newDeploy\backup\PPO.zip -Destination D:\newDeploy\backup\$i
Start-BitsTransfer -Source \\$i\d$\newDeploy\backup\TiMan.zip -Destination D:\newDeploy\backup\$i
}
foreach($i in $webServers) {
Remove-Item \\$i\d$\newDeploy\backup\OffM.zip
Remove-Item \\$i\d$\newDeploy\backup\Others.zip
Remove-Item \\$i\d$\newDeploy\backup\PPO.zip
Remove-Item \\$i\d$\newDeploy\backup\TiMan.zip
}
[System.Reflection.Assembly]::LoadFrom("D:\\newDeploy\\Ionic.Zip.dll");
$directoryToZip = "D:\newDeploy\backup"
$date = get-date -format "M-d-yyyy"
$zipfile = new-object Ionic.Zip.ZipFile
$e = $zipfile.AddSelectedFiles("name != '*.e2e'",$directoryToZip, "",1)
$zipfile.Save("D:\\newDeploy\\backup\\"+$date+"_WEBbackup.zip")
$zipfile.Dispose()

There is a debug messages setting like that - $DebugPreference
It's default is SilentlyContinue. See if it is set to something else.
It would help if you also showed the difference in output. It could also be a verbose output as controlled by the $VerbosePreference
Look here to know about the preference varibales - http://technet.microsoft.com/en-us/library/dd347731.aspx
Update:
Add a [void] before [System.Reflection.Assembly]::LoadFrom statements so that the output doesn't pollute the script output.

Related

How to get the 'status' column value in Windows explorer by PowerShell or java

when we open a windows explorer, we will see multi-column, like this:
now, I want to get the status column(Circled in red) value by PowerShell or java, Is there a way to do it?
You can include below function and modify as per your need in Powershell.
Below Powershell function can be used to get all details or properties of an item in file explorer.
function Get-FileMetaData {
<#
.SYNOPSIS
Small function that gets metadata information from file providing similar output to what Explorer shows when viewing file
.DESCRIPTION
Small function that gets metadata information from file providing similar output to what Explorer shows when viewing file
.PARAMETER File
FileName or FileObject
.EXAMPLE
Get-ChildItem -Path $Env:USERPROFILE\Desktop -Force | Get-FileMetaData | Out-HtmlView -ScrollX -Filtering -AllProperties
.EXAMPLE
Get-ChildItem -Path $Env:USERPROFILE\Desktop -Force | Where-Object { $_.Attributes -like '*Hidden*' } | Get-FileMetaData | Out-HtmlView -ScrollX -Filtering -AllProperties
.NOTES
#>
[CmdletBinding()]
param (
[Parameter(Position = 0, ValueFromPipeline)][Object] $File,
[switch] $Signature
)
Process {
foreach ($F in $File) {
$MetaDataObject = [ordered] #{}
if ($F -is [string]) {
$FileInformation = Get-ItemProperty -Path $F
} elseif ($F -is [System.IO.DirectoryInfo]) {
#Write-Warning "Get-FileMetaData - Directories are not supported. Skipping $F."
continue
} elseif ($F -is [System.IO.FileInfo]) {
$FileInformation = $F
} else {
Write-Warning "Get-FileMetaData - Only files are supported. Skipping $F."
continue
}
$ShellApplication = New-Object -ComObject Shell.Application
$ShellFolder = $ShellApplication.Namespace($FileInformation.Directory.FullName)
$ShellFile = $ShellFolder.ParseName($FileInformation.Name)
$MetaDataProperties = [ordered] #{}
0..400 | ForEach-Object -Process {
$DataValue = $ShellFolder.GetDetailsOf($null, $_)
$PropertyValue = (Get-Culture).TextInfo.ToTitleCase($DataValue.Trim()).Replace(' ', '')
if ($PropertyValue -ne '') {
$MetaDataProperties["$_"] = $PropertyValue
}
}
foreach ($Key in $MetaDataProperties.Keys) {
$Property = $MetaDataProperties[$Key]
$Value = $ShellFolder.GetDetailsOf($ShellFile, [int] $Key)
if ($Property -in 'Attributes', 'Folder', 'Type', 'SpaceFree', 'TotalSize', 'SpaceUsed') {
continue
}
If (($null -ne $Value) -and ($Value -ne '')) {
$MetaDataObject["$Property"] = $Value
}
}
if ($FileInformation.VersionInfo) {
$SplitInfo = ([string] $FileInformation.VersionInfo).Split([char]13)
foreach ($Item in $SplitInfo) {
$Property = $Item.Split(":").Trim()
if ($Property[0] -and $Property[1] -ne '') {
$MetaDataObject["$($Property[0])"] = $Property[1]
}
}
}
$MetaDataObject["Attributes"] = $FileInformation.Attributes
$MetaDataObject['IsReadOnly'] = $FileInformation.IsReadOnly
$MetaDataObject['IsHidden'] = $FileInformation.Attributes -like '*Hidden*'
$MetaDataObject['IsSystem'] = $FileInformation.Attributes -like '*System*'
if ($Signature) {
$DigitalSignature = Get-AuthenticodeSignature -FilePath $FileInformation.Fullname
$MetaDataObject['SignatureCertificateSubject'] = $DigitalSignature.SignerCertificate.Subject
$MetaDataObject['SignatureCertificateIssuer'] = $DigitalSignature.SignerCertificate.Issuer
$MetaDataObject['SignatureCertificateSerialNumber'] = $DigitalSignature.SignerCertificate.SerialNumber
$MetaDataObject['SignatureCertificateNotBefore'] = $DigitalSignature.SignerCertificate.NotBefore
$MetaDataObject['SignatureCertificateNotAfter'] = $DigitalSignature.SignerCertificate.NotAfter
$MetaDataObject['SignatureCertificateThumbprint'] = $DigitalSignature.SignerCertificate.Thumbprint
$MetaDataObject['SignatureStatus'] = $DigitalSignature.Status
$MetaDataObject['IsOSBinary'] = $DigitalSignature.IsOSBinary
}
[PSCustomObject] $MetaDataObject
}
}
}
Reference :
Follow Below Link for the complete tutorial.
https://evotec.xyz/getting-file-metadata-with-powershell-similar-to-what-windows-explorer-provides/

Powershell script to install font family

Below is my script istalling Monserrat fonts from zip file. I can't figure how to check if a font already installed. After installation I can open folder C:\Windows\Fonts\Montserrat and I see al of them. When I am running script second time, it is not recognize existance of this folder. Where is my mistake?
$Source = "Montserrat.zip"
$FontsFolder = "FontMontserrat"
Expand-Archive $Source -DestinationPath $FontsFolder
$FONTS = 0x14
$CopyOptions = 4 + 16;
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace($FONTS)
$allFonts = dir $FontsFolder
foreach($File in $allFonts)
{
If((Test-Path "C:\Windows\Fonts\Montserrat") -eq $True)
{
echo "Font $File already installed"
}
Else
{
echo "Installing $File"
$CopyFlag = [String]::Format("{0:x}", $CopyOptions);
$objFolder.CopyHere($File.fullname,$CopyFlag)
}
}
Finally my script:
$Source = "Montserrat.zip"
$FontsFolder = "FontMontserrat"
Expand-Archive $Source -DestinationPath $FontsFolder -Force
$FONTS = 0x14
$CopyOptions = 4 + 16;
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.Namespace($FONTS)
$allFonts = dir $FontsFolder
foreach($font in Get-ChildItem -Path $fontsFolder -File)
{
$dest = "C:\Windows\Fonts\$font"
If(Test-Path -Path $dest)
{
echo "Font $font already installed"
}
Else
{
echo "Installing $font"
$CopyFlag = [String]::Format("{0:x}", $CopyOptions);
$objFolder.CopyHere($font.fullname,$CopyFlag)
}
}
I am running this script by following cmd:
set batchPath=%~dp0
powershell.exe -noexit -file "%batchPath%InstMontserrat.ps1"
I don't have to run it as administrator, but user have admin permissions.
Corrections of your script based on my comment assuming Windows 10:
# well-known SID for admin group
if ('S-1-5-32-544' -notin [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
throw 'Script must run as admin!'
}
$source = 'Montserrat.zip'
$fontsFolder = 'FontMontserrat'
Expand-Archive -Path $source -DestinationPath $fontsFolder
foreach ($font in Get-ChildItem -Path $fontsFolder -File) {
$dest = "C:\Windows\Fonts\$font"
if (Test-Path -Path $dest) {
"Font $font already installed."
}
else {
$font | Copy-Item -Destination $dest
}
}
If you do not want to install the font on OS level but only make it available for programs to use until reboot you may want to use this script that:
Will fail/throw if it cannot register/unregister font.
Broadcasts WM_FONTCHANGE to inform all windows that fonts have changed
Does not require administrator privileges
Does not install fonts in Windows, only makes them available for all programs in current session until reboot
Has verbose mode for debugging
Does not work with font folders
Usage:
register-fonts.ps1 [-v] [-unregister <PATH>[,<PATH>...]] [-register <PATH>[,<PATH>...]] # Register and unregister at same time
register-fonts.ps1 [-v] -unregister <PATH>
register-fonts.ps1 [-v] -register <PATH>
register-fonts.ps1 [-v] <PATH> # Will register font path
Param (
[Parameter(Mandatory=$False)]
[String[]]$register,
[Parameter(Mandatory=$False)]
[String[]]$unregister
)
# Stop script if command fails https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error
$ErrorActionPreference = "Stop"
add-type -name Session -namespace "" -member #"
[DllImport("gdi32.dll")]
public static extern bool AddFontResource(string filePath);
[DllImport("gdi32.dll")]
public static extern bool RemoveFontResource(string filePath);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam = 0, int lParam = 0);
"#
$broadcast = $False;
Foreach ($unregisterFontPath in $unregister) {
Write-Verbose "Unregistering font $unregisterFontPath"
# https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-removefontresourcea
$success = [Session]::RemoveFontResource($unregisterFontPath)
if (!$success) {
Throw "Cannot unregister font $unregisterFontPath"
}
$broadcast = $True
}
Foreach ($registerFontPath in $register) {
Write-Verbose "Registering font $registerFontPath"
# https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontresourcea
$success = [Session]::AddFontResource($registerFontPath)
if (!$success) {
Throw "Cannot register font $registerFontPath"
}
$broadcast = $True
}
if ($broadcast) {
# HWND_BROADCAST https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
$HWND_BROADCAST = New-Object IntPtr 0xffff
# WM_FONTCHANGE https://learn.microsoft.com/en-us/windows/win32/gdi/wm-fontchange
$WM_FONTCHANGE = 0x1D
Write-Verbose "Broadcasting font change"
# Broadcast will let other programs know that fonts were changed https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
$success = [Session]::PostMessage($HWND_BROADCAST, $WM_FONTCHANGE)
if (!$success) {
Throw "Cannot broadcase font change"
}
}
The script was inspired by this gist https://gist.github.com/Jaykul/d53a16ce5e7d50b13530acb4f98aaabd

Copying files from Multiple Folders Where the File Name is a part of the folder

'I am trying to copy multiple files from multiple folders into another folder. The folders have a part of the file name in them.
For example -
I want to copy all the files that have the name "Phone" or "cell" and the serial number as a part of the file name. Each sub folder has the serial number as a part of the folder name.
C:\shared\112\products\112.phone blah blah.txt
C:\shared\112\products\112.my cell.txt
C:\shared\113\products\113.ugly phone.txt
C:\shared\113\products\113.the cell.txt
C:\shared\114\products\114.pretty phone.txt
C:\shared\115\products\115.phone lazy.txt
C:\shared\115\products\115.celly cell.txt
The problem is there are 20,000 serial numbers so I want to set up a list of serial numbers and pull the file based on a set of serial number.
Here is my script but it is not pulling anything.'
$FirstSearchlist = #(“112”, “113”)
$SecondSearchlist = #("phone","cell")
$dirArray = #("c:\Shared\")
$NotFound = "Not Found"
cls
function Recurse([string]$path) {
$fc = new-object -com scripting.filesystemobject
$folder = $fc.getfolder($path)
foreach ($i in $folder.files) {
[string]$FullPath = $i.Path
[string]$FileName = $i.Name
foreach($first in $FirstSearchlist) {
if ($filename.ToUpper().Contains($first.ToUpper())) {
foreach($second in $SecondSearchlist) {
if ($filename.ToUpper().Contains($second.ToUpper())) {
Write-Host $Fullpath
Copy-Item $Fullpath -Destination "C:\Shared\Phones" -Recurse
}
}
}
}
}
foreach ($i in $folder.subfolders) {
Recurse($i.path)
}
}
function main() {
foreach ($i in $FirstSearchlist){
$NewFolder = $dirArray + $i
foreach($SearchPath in $NewFolder) {
Recurse $SearchPath
}
}
}
main
This worked for me testing with the example set provided (but note in my testing C:\Shared is empty, may want to adjust down your folder tree depending):
Function Get-FileMatches($Filter){
$fileMatches = Get-ChildItem -Path "C:\Shared" -Recurse | ? {$_.Mode -notmatch 'd' -and $_.Name -match $Filter -and ($_.Name -match $SecondSearchlist[0] -or $_.Name -match $SecondSearchlist[1])}
return $fileMatches
}
Function Run-Script() {
$FirstSearchlist = #(“112”, “113”)
$SecondSearchlist = #("phone","cell")
$allMatches = #()
$phonesFolderExists = Test-Path "C:\Shared\Phones"
if($phonesFolderExists -eq $False)
{
New-Item -Path "C:\Shared\Phones" -ItemType Directory -Force
}
foreach($listItem in $FirstSearchList) {
$currentMatches = Get-FileMatches -Filter $listItem
if($currentMatches -ne $null)
{
foreach($item in $currentMatches)
{
$allMatches += $item
}
}
}
if($allMatches -ne $null)
{
foreach($item in $allMatches)
{
Copy-Item -Path $item.FullName -Destination "C:\Shared\Phones"
}
}
}
Run-Script

Get free disk space for different servers with separate credentials

I'm trying to query Disk space info on Grid box and Export it to CSV.
I was able to use Marc Weisel's script to make it use different credentials. I used computers.csv
to store the computer name and referenced credentials. This is working although the problem I'm facing is that Grid box opens for all the servers mentioned in the csv.
I want to view all disk space information on the same grid box.
Below are my script and module I'm using
Import-Module D:\get.psm1
Import-Module D:\out-CSV.psm1
$ComputerList = Import-Csv -Path d:\Computers.csv;
#$servers = 'laptop-pc','laptop-pc','laptop-pc'
$CredentialList = #{
Cred1 = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'laptop-pc\laptop', (ConvertTo-SecureString -String 'tamboli' -AsPlainText -Force);
#Cred2 = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'tnt\administrator', (ConvertTo-SecureString -String 'Atlantic12' -AsPlainText -Force);
}
foreach ($computer in $ComputerList )
{
Get-DiskFree -ComputerName $Computer.Name -Credential $CredentialList[$Computer.Credential] -Format | ? { $_.Type -like '*fixed*' } | select * -ExcludeProperty Type |
}
get.ps1
function Get-DiskFree
{
[CmdletBinding()]
param
(
[Parameter(Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[Alias('hostname')]
[Alias('cn')]
[string[]]$ComputerName = $env:COMPUTERNAME,
[Parameter(Position=1,
Mandatory=$false)]
[Alias('runas')]
[System.Management.Automation.Credential()]$Credential =
[System.Management.Automation.PSCredential]::Empty,
[Parameter(Position=2)]
[switch]$Format
)
BEGIN
{
function Format-HumanReadable
{
param ($size)
switch ($size)
{
{$_ -ge 1PB}{"{0:#.#'P'}" -f ($size / 1PB); break}
{$_ -ge 1TB}{"{0:#.#'T'}" -f ($size / 1TB); break}
{$_ -ge 1GB}{"{0:#.#'G'}" -f ($size / 1GB); break}
{$_ -ge 1MB}{"{0:#.#'M'}" -f ($size / 1MB); break}
{$_ -ge 1KB}{"{0:#'K'}" -f ($size / 1KB); break}
default {"{0}" -f ($size) + "B"}
}
}
$wmiq = 'SELECT * FROM Win32_LogicalDisk WHERE Size != Null AND DriveType >= 2'
}
PROCESS
{
foreach ($computer in $ComputerName)
{
try
{
if ($computer -eq $env:COMPUTERNAME)
{
$disks = Get-WmiObject -Query $wmiq `
-ComputerName $computer -ErrorAction Stop
}
else
{
$disks = Get-WmiObject -Query $wmiq `
-ComputerName $computer -Credential $Credential `
-ErrorAction Stop
}
if ($Format)
{
# Create array for $disk objects and then populate
$diskarray = #()
$disks | ForEach-Object { $diskarray += $_ }
$diskarray | Select-Object #{n='Name';e={$_.SystemName}},
#{n='Vol';e={$_.DeviceID}},
#{n='Size';e={Format-HumanReadable $_.Size}},
#{n='Used';e={Format-HumanReadable `
(($_.Size)-($_.FreeSpace))}},
#{n='Avail';e={Format-HumanReadable $_.FreeSpace}},
#{n='Use%';e={[int](((($_.Size)-($_.FreeSpace))`
/($_.Size) * 100))}},
#{n='FS';e={$_.FileSystem}},
#{n='Type';e={$_.Description}}
}
else
{
foreach ($disk in $disks)
{
$diskprops = #{'Volume'=$disk.DeviceID;
'Size'=$disk.Size;
'Used'=($disk.Size - $disk.FreeSpace);
'Available'=$disk.FreeSpace;
'FileSystem'=$disk.FileSystem;
'Type'=$disk.Description
'Computer'=$disk.SystemName;}
# Create custom PS object and apply type
$diskobj = New-Object -TypeName PSObject `
-Property $diskprops
$diskobj.PSObject.TypeNames.Insert(0,'BinaryNature.DiskFree')
Write-Output $diskobj
}
}
}
catch
{
# Check for common DCOM errors and display "friendly" output
switch ($_)
{
{ $_.Exception.ErrorCode -eq 0x800706ba } `
{ $err = 'Unavailable (Host Offline or Firewall)';
break; }
{ $_.CategoryInfo.Reason -eq 'UnauthorizedAccessException' } `
{ $err = 'Access denied (Check User Permissions)';
break; }
default { $err = $_.Exception.Message }
}
Write-Warning "$computer - $err"
}
}
}
END {}
}
You need to append the result of Get-DiskFree to an array in the loop, and pipe that result to the Grid View from outside your loop:
foreach ($computer in $ComputerList )
{
$result += Get-DiskFree -ComputerName $Computer.Name -Credential $CredentialList[$Computer.Credential] -Format | ? { $_.Type -like '*fixed*' } | select * -ExcludeProperty Type
}
$result | Out-GridView
Or, better yet, pipe the result from outside the Foreach-Object loop:
$ComputerList | % {
Get-DiskFree -ComputerName $_.Name -Credential $CredentialList[$_.Credential] -Format | ? { $_.Type -like '*fixed*' } | select * -ExcludeProperty Type
} | Out-GridView

Powershell input validition

I am trying to only allow a user to enter 2 letters when they rename a file if its exists.
It is not working as I wanted it. I am allowed to enter numbers.
if ($RenameLargeFiles.Length -gt '2') {
Write-Host " You may only enter 2 letters."
Pause
Clear-Host
Rename-LargeFiles
} else {
Rename-Item -Path $LargeFiles $RenameLargeFiles".txt"
$LargeFiles = $RenameLargeFiles
Set-Content -Value $Files -Path $LargeFiles
}
}
Set-StrictMode –Version Latest
$LargeFiles = "C:\PSScripts\LargeFiles.txt"
$PSScripts = "C:\PSScripts"
$TestPSScripts = Test-Path "C:\PSScripts"
switch ($TestPSScripts) {
'False' { New-Item -Type directory -Path $PSScripts }
}
function Test-Files {
$Files8 = ""
$Files8 = Read-Host " Please Enter the Complete Path. "
$TFiles8 = Test-Path $files8
if ($TFiles8 -eq 'True') {
Write-Host $Files8 "LOCATED."
} else {
Write-Host $Files8 "NOT FOUND"
Pause
Clear-Host
Test-Files
}
}
function Test-LargeFiles {
$LargeFiles = "C:\PSScripts\LargeFiles.txt"
$TestLargeFiles = Test-Path $LargeFiles
if ($TestLargeFiles -eq 'True') {
Write-Host $LargeFiles "already present"
Rename-LargeFiles
} else {
Write-Host $LargeFiles "NOT FOUND."
Write-Host $LargeFiles "created"
}
}
function Rename-LargeFiles {
$LargeFiles = "C:\PSScripts\LargeFiles.txt"
[string] $RenameLargeFiles = Read-Host " Please Enter 2 letters to rename" $LargeFiles
if ($RenameLargeFiles.Length -gt '2') {
Write-Host " You may only enter 2 letters."
Pause
Clear-Host
Rename-LargeFiles
} else {
Rename-Item -Path $LargeFiles $RenameLargeFiles".txt"
$LargeFiles = $RenameLargeFiles
Set-Content -Value $Files -Path $LargeFiles
}
}
Test-Files
$Files = Get-ChildItem -Recurse $Files8 | Sort-Object -Descending -Property Length | Select-Object -First 10
Test-LargeFiles
Add-Content -Value $Files -Path $LargeFiles
pause
Use a regex like so:
if ($RenameLargeFiles -notmatch '[aA-zZ]{2}') {
... display error message
}

Resources