Mount Point in PowerShell - powershell

I'm trying to create a mount point using Powershell. it's done locally, and here is the code & issue i'm having.
$choice = "t"
New-Item -ItemType directory -Path "E:\Data\Riptide\Ariis\Ris\Docs\interPrimary1\"
$orgdrive = "E:\Data\Riptide\Ariis\Ris\Docs\interPrimary1\"
$driveLetter= $Choice + ":\"
$driveinfo=get-wmiobject win32_volume | where { $_.driveletter -eq $choice + ":" } | select-object DeviceID
Mountvol $orgdrive $driveinfo
When executed, I get that the parameter is incorrect.
Thanks in advance.

You just have to try :
mountvol $orgdrive $driveinfo.DeviceID
For the future you can test :
$driveinfo| Get-Member
You can find here a tool that allow you to test the command line parameters.

Related

Powershell Throw Causing Variables to Clear?

My PowerShell script just checks multiple servers to make sure the input* and output* directories are clear of any files.
I'm simply trying to output to console the results of a GCI call prior to throwing an error message. However, when I uncomment the "throw" line, the $inputFiles and $outputFiles no longer output to the console. Below is the code:
$allServers = #(
"server1.com",
"server2.com")
foreach ($server in $allServers) {
$inputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\input*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
$outputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\output*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
if ($inputFiles -eq $NULL -and $outputFiles -eq $NULL) {
Write-Host "Environment is ready for statement processing."
}
else {
Write-Host "Environment is NOT ready for statement processing."
Write-Host "The following files exist in input/output: `n"
$inputFiles
$outputFiles
#Throw "Files exist in input/output. See above for details."
}
}
Below is the console output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
FullName
--------
\\server1.com\C$\jobs\statements\input\asdasd.txt
\\server1.com\C$\jobs\statements\input_254\asdasd.txt
\\server1.com\C$\jobs\statements\input_test\asdasd.txt
\\server2.com\C$\jobs\statements\input\CUSSTAT10302021.245
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021.zip
And below is the console output when I uncomment the "throw" line:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Files exist in input/output. See above for details.
At C:\jobs\statements\bin\Statements-EnvironmentCheck.ps1:47 char:9
+ Throw "Files exist in input/output. See above for details."
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Files exist in ...ve for details.:String) [], RuntimeException
+ FullyQualifiedErrorId : Files exist in input/output. See above for details.
I know I have some error output cleanup to perform in order to include all the servers that might have files present, but please ignore that for now.
What you're experiencing is explained in this answer and this answer, basically you need to implement Out-Host \ Out-Default:
$inputFiles, $outputFiles | Out-Host # Should fix the problem
# possibly `throw` might require this too
throw "Files exist in input/output. See above for details." | Out-Host
However, I feel is worth showing you a better way to approach your code, returning a unified array of objects which you can filter, sort and export.
$allServers = #(
"server1.com"
"server2.com"
)
$result = foreach ($server in $allServers) {
# use `-File` instead of `! $_.PSIsContainer`
$out = #{
in = Get-ChildItem "\\$server\C$\jobs\statements\input*\" -Recurse -File
out = Get-ChildItem "\\$server\C$\jobs\statements\output*\" -Recurse -File
}
# if $out['in'] and $out['out'] are `$null`, Ready is `$true`
[pscustomobject]#{
Ready = -not($out['in'] -or $out['out'])
Server = $server
Files = $out
}
}
Now, if you want to see which servers are Ready (no files in input and output):
$result.where{ $_.Ready }
And if you want to see which servers are not Ready, and have a list of the files:
$result.where{ -not $_.Ready }.foreach{
foreach($file in $_.Files.PSBase.Values.FullName) {
[pscustomobject]#{
Server = $_.Server
Files = $file
}
}
}

Test-Path for everyone

I'm currently creating a script for a group of users could use it. I use Test-Path "C:\Users\vincentw\allapps.txt to verify if allapps.txt exists on my local system before running the script:
if (!(Test-Path "C:\Users\vincentw\allapps.txt")) {
"All sw/apps" >> allapps.txt
"-------------------------------------------------------" >> allapps.txt
(Get-WmiObject Win32_Product |
where {$_.Vendor -notmatch "Advanced"} |
Format-List name, Vendor, Version |
Out-String).Trim() >> allapps.txt
"-------------------------------------------------------" >> allapps.txt
} else {
Write-Host "WARNING: File already exists!"
break
}
However, the script verifying only works on my local system. I'm wondering is there any way my local username - 'vincentw' could be replaced to make the script available check every user's local path on their own systems?
If the script will be run from their user on their computer then you could use $env:USERPROFILE
Test-Path "$($env:USERPROFILE)\allapps.txt"
If you want to do it on all profiles you can do something like this
Get-ChildItem "C:\Users\" -Directory | foreach-object{
If(!(test-path "$($_.FullName)\allapps.txt")){
"Missing : $($_.FullName)\allapps.txt"
}Else{
"Found : $($_.FullName)\allapps.txt"
}
}

get-content : Cannot find path 'PATH_TO_FILE_' because it does not exsist

I am writing a PS Script to try and locate a folder on a remote server. Here is the code:
# Set file to be tested for, put everything after c:\
# “c:\Users\Default” is the example path
$filetofind = "EventLogs"
# Hostnames TXT Location
$hostnamestxt = "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
# Destination file for Online Machines
$onlinetxt = "C:\Scripts\Powershell_Remote_File_Query\Machines_with_file.txt"
# Destination file for Offline Machines
$offlinetxt = "C:\Scripts\Powershell_Remote_File_Query\Offline_Machines.txt"
##########################################################
# Begin Executing Script – Do Not Edit Below This Line
##########################################################
$computers = get-content “$hostnamestxt”
write-host “———————————————-”
write-host “Scanning hostnames from $hostnamestxt…”
write-host “———————————————-”
foreach($computer in $computers)
{
ping -n 1 $computer >$null
if($lastexitcode -eq 0)
{
if(test-path “\\$computer\c$\$filetofind”)
{
echo “$computer” | Out-File -Append “$onlinetxt”
write-host “File FOUND on $computer”
}
else
{write-host “File NOT found on $computer”}
}
else
{
echo “$computer” | Out-File -Append “$offlinetxt”
write-host “$computer is OFFLINE/DID NOT RESPOND TO PING”
}
}
write-host “———————————————-”
write-host “Script has completed please check output.”
write-host “Hosts with file output location – $onlinetxt”
write-host “Hosts that were unpingable output location – $offlinetxt”
write-host “———————————————-“
I get this error when running the script:
get-content : Cannot find path 'C:\Scripts\Powershell_Remote_File_Query\“€' because it does not exist.
At C:\Scripts\Powershell_Remote_File_Query\Powershell_Remote_File_Query_Script.ps1:24 char:18
+ $computers = get-content “$hostnamestxtâ€
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Scripts\Powe...ile_Query\“€:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Both the script itself and the txt file are in the same directory. Please forgive me I'm new to Powershell and not a programmer by any means.
Instead of doing this...
$hostnamestxt = "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
$computers = get-content “$hostnamestxt”
Try just doing this...
$computers = get-content "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
I understand what you are trying to do should result to the same thing, yet, let's just try to eliminate that extra thing, and give it a shot to see if you get a different result.
Also, if that file you are reading is on a remote host, then you should be using the UNC file share path, not your local C: drive. Just assuming a bit here.

Get Folder NTFS ACL on long path name

I have a PS script that will return NTFS ACLs if an individual user is assigned, works well until I hit a path exceeding 260 characters. I've found a lot of information on the path too long problem and some work-arounds but I'm struggling to integrate a solution into my script. Any suggestions?
Thanks!
$DateStart = Get-Date
$Path = "E:\"
$PermittedOU1 = "OU=Groups,dc=chiba,dc=localt"
$PermittedOU3 = "OU=System Accounts,OU=Accounts,dc=chiba,dc=local"
$PermittedACL1 = get-adgroup -Filter * -SearchBase $PermittedOU1
$PermittedACL3 = get-aduser -Filter * -SearchBase $PermittedOU3
$ObjectPathItem = Get-ChildItem -path $Path -Recurse | where-object {$_.PsIsContainer} | foreach- object -process { $_.FullName }
$howmany=0
$Logfilename = "C:\Users\administrator\Documents\$(get-date -f yyyy-MM-dd-hh-mm).csv"
Add-Content $Logfilename "$DateStart`n"
$totalfolders=0
$i=0
ForEach ($Folder in $ObjectPathItem)
{
$totalfolders++
}
Foreach ($Folder in $ObjectPathItem)
{
$ObjectACL = Get-ACL -Path $Folder
$i++
$howmany=0
Write-Progress -id 1 -Activity "Folder Recursion" -status "Folders Traversed: " -PercentComplete (($i / $totalfolders) * 100)
Foreach ($ACL in $ObjectACL.access)
{
$ACLstring = $ACL.identityreference.Value
$ACLstring = $ACLstring.Replace("CHIBA\","")
if (($ACLstring -notin $PermittedACL1.name)`
-and ($ACLstring -notin $PermittedACL3.SamAccountName)`
-and ($ACLstring -notin "NT AUTHORITY\SYSTEM") `
-and ($ACLstring -notin "BUILTIN\Administrators") `
-and ($ACLstring -notin "CREATOR OWNER"))
{
$newline = "`"$Folder`"" + "," + "$ACLString"
Add-Content $Logfilename "$newline"
$howmany+=1
}
else {
$howmany+=1
}
}
}
$DateEnd = Get-Date
Add-Content $Logfilename "`n`n$DateEnd"
One option you can usually use is to create a mapped drive using New-PSDrive. Something like:
Try{
$ObjectACL = Get-ACL -Path $Folder
}
Catch{
$SubPathLength = $Folder.FullName.substring(0,200).LastIndexOf('\')
$NewTempPath = $Folder.FullName.SubString(0,$SubPathLength)
New-PSDrive -Name Temp4ACL -Provider FileSystem -Root $NewTempPath
$ObjectACL = Get-ACL "Temp4ACL:$($Folder.FullName.SubSTring($SubPathLength,$Folder.FullName.Length-$SubPathLength))"
}
That will find the last \ before the 200th character in the path, grab a substring of the full path up to the end of that folder's name and create a temp drive of it, then get the ACL based off the temp drive and the remaining path. So this path:
C:\Temp\Subfolder\Really Long Folder Name\Another Subfolder\ABCDEFGHIJKLMNOPQRSTUVWXYZ\We Are Really Pushing It Now\Im Running Out Of Folder Name Ideas\Hello My Name Is Inigo Montoya\You Killed My Father Prepare To Die\ReadMe.txt
Gets cut at the second to last backslash. I would end up getting the ACL from:
Temp4ACL:\You Killed My Father Prepare To Die\ReadMe.txt
Easy way is to use "\\?" to support 32,767 characters.
$folder = "C:\MyFolder"
icacls "\\?\$folder"
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364963(v=vs.85).aspx
In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function (GetFullPathNameW), and prepend "\\?\" to the path.
Okay, this question is quite old but for those coming here as of today like myself I provide this information that I found through Google:
Microsoft Technet Script Center lists a "File System Security PowerShell Module" which claims that since version 3.0 it "leverages the AlphaFS (http://alphafs.codeplex.com) to work around the MAX_PATH limitation of 260 characters". At the time of this writing the module is at version 4.2.3.
The general idea of this module is described as "PowerShell only offers Get-Acl and Set-Acl but everything in between getting and setting the ACL is missing. This module closes the gap."
So without having tried this myself I suppose it should help in solving the OPs problem.
The module is also featured in a post by the "Hey, Scripting Guy! Blog".

Powershell WMI Query failing when executed from Task Scheduler

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