0

Ok so I'm having a weird error with the following script:

$ErrorActionPreference = "silentlycontinue"
Try {

If (Test-Path \\Deploy\MyDocSize\live_docs_info.csv -PathType Leaf) {
    $runscript = Get-ChildItem "C:\Users\$env:username\Documents" -Recurse | Measure-Object -    property length -sum | Select @{Label="FolderSize";Expression={"{0:N2}" -f ($_.Sum / 1MB)}}, @{Label="Username";Expression={$env:username}} |
    ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -Append -Encoding ascii -FilePath \\Deploy\MyDocSize\live_docs_info.csv -ErrorAction SilentlyContinue
    }

Else {
    $runscript = Get-ChildItem "C:\Users\$env:username\Documents" -Recurse | Measure-Object -property length -sum | Select @{Label="FolderSize";Expression={"{0:N2}" -f ($_.Sum / 1MB)}}, @{Label="Username";Expression={$env:username}} |
    ConvertTo-Csv -NoTypeInformation | Select-Object | Out-File -Append -Encoding ascii -FilePath \\Deploy\MyDocSize\live_docs_info.csv
    }
}

Finally {

If (Test-Path \\Deploy\MyDocSize\docs_info.csv -PathType Leaf) {
    $runscript = Get-ChildItem "C:\Users\$env:username\Documents" -Recurse | Measure-Object -property length -sum | Select @{Label="FolderSize";Expression={"{0:N2}" -f ($_.Sum / 1MB)}}, @{Label="Username";Expression={$env:username}} |
    ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -Append -Encoding ascii -FilePath \\Deploy\MyDocSize\docs_info.csv -ErrorAction SilentlyContinue
    }

Else {
    $runscript = Get-ChildItem "C:\Users\$env:username\Documents" -Recurse | Measure-Object -property length -sum | Select @{Label="FolderSize";Expression={"{0:N2}" -f ($_.Sum / 1MB)}}, @{Label="Username";Expression={$env:username}} |
    ConvertTo-Csv -NoTypeInformation | Select-Object | Out-File -Append -Encoding ascii -FilePath \\Deploy\MyDocSize\docs_info.csv
    }
}

This script takes the current username and size of that user's My Documents folder and exports it to a csv file. I have exported to two different csv files, and in case one is open when the script is run it will just keep running and write to the second one. In case both are open, it will not do anything.

Basically this script works for me, however when any other user tries to run it, it will not work. I suspect the $env:username is at fault but I'm not sure. Any help would be greatly appreciated!

ZEM
  • 21
  • 1
  • 10
  • 1
    When you say it "will not work" for other users - what does that mean? Does it throw an error? – Kohlbrr Oct 22 '14 at 17:54
  • 1
    $env:Username allways refers to the user that has created the powershell session, not to the currently logged on user. So if the user starts the script with another credential it will fail. may this be the problem? – Paul Oct 22 '14 at 18:03
  • By not working I mean it doesn't create the 2 csv files with the info I specified. Paul can you explain this, "$env:Username always refers to the user that has created the powershell session," a little more? I had thought that whenever someone logs in and runs the script they are creating a powershell session with their current username. If this is not the case, and if I created the session and send the script to others with me still being the creator of the session, how can i capture whatever username is currently logged in? Thanks so much for your answer and any help you can provide me. – ZEM Oct 22 '14 at 18:09
  • Does the script run at all for other users? Do they even have access? – Ansgar Wiechers Oct 22 '14 at 18:19
  • Are you able to see the exceptions being thrown from the script? for example if you are executing this using `PowerShell.exe` via `cmd` you could redirect all output to a "C:\Users\USERNAME\script-output.txt" with `1> %USERPROFILE%\script-output.txt 2>&1`. You could get similar results through your own script using your existing `try { } finally { }` blocks. – Richard Slater Oct 22 '14 at 18:36
  • @ZachMinot Yes when a user is just double-clicking the file the user will be the creator of the session. But for example if your users dont have enough rights to run powershell scripts and start it with another credential this user will be in the env variable. Or in case you use psremoting the variable will refer to the local accountname that opened the connection. You can allways get the logged on user like this: `Get-WmiObject Win32_ComputerSystem | select username` or if you use powershell v3 use `Get-CimInstance Win32_ComputerSystem | select username` – Paul Oct 22 '14 at 18:45
  • If you want to use this to access the profile path then rather follow RichardSlater´s suggestion – Paul Oct 22 '14 at 18:47
  • No exceptions being thrown that I can see. I'm curious as to why I would need redirect the output to somewhere else, since all I'm trying to do is get the current username, as the current username is in the file path to the my documents folder. Also I tried to run %USERPROFILE% in powershell but it doesn't recognize it. Am I just misunderstanding this? – ZEM Oct 22 '14 at 18:59
  • Paul why can't I use your suggestion? Just wondering. I basically want to access this location: C:\Users\Currently_logged_on_user\My Documents so would I be able to use your method and do: $user = Get-WmiObject Win32_ComputerSystem | select username C:\Users\$user\My Documents I'm using PS version 2 – ZEM Oct 22 '14 at 19:02
  • `%USERPROFILE%` is the the Command Prompt's syntax for accessing the value of the `USERPROFILE` environment variable, the equivalent in PowerShell is `$env:USERPROFILE`. It is not uncommon to execute PowerShell scripts via the command prompt (i.e. cmd.exe) so that you can bypass the Execution Policy: `PowerShell -ExecutionPolicy Unrestricted -Command C:\path\to\script` – Richard Slater Oct 22 '14 at 19:18

1 Answers1

0

NOTE: this is a bit of a guess on my part, however I have recently bumped into a similar problem, and found the following worked for me.

There is not necessarily an one-to-one mapping between a users $env:username and their My Documents folder. For example if there is a permenant problem loading the profile from C:\Users\$env:username then windows will allocate a slightly different name, e.g. username_000. Equally certain versions of windows ended up creating user profiles using the short name, e.g. userna~1, rather than the long name. Regardless of the cause there are two simple solutions:

The Pure Powershell Way

Join-Path $env:USERPROFILE "Documents"

It is that simple, this however is not bullet proof as it is possible to move or rename the Documents to something else which would result in errors or odd results being added to the CSV file. It would work in 90-95% of cases.

The .NET Framework Environment Way

[Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)

It's a bit more of a mouthful, but essentially you are leveraging the .NET frameworks ability to interrogate the System Environment and ask where the users MyDocuments folder is.

Richard Slater
  • 6,313
  • 4
  • 53
  • 81
  • This what I get when trying to use the first method you listed to dynamically access my documents folder: Get-ChildItem Join-Path $env:USERPROFILE "Documents" Get-ChildItem : A positional parameter cannot be found that accepts argument 'Documents'. and the second method: Get-ChildItem [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments) Get-ChildItem : Cannot find a provider with the name '[Environment]'. Am I just doing it wrong? – ZEM Oct 22 '14 at 18:54
  • Try assigning the value of the documents directory as follows: `$documentFolder = Join-Path $env:USERPROFILE "Documents"; Get-ChildItem $documentFolder;` Or alternatively: `$documentFolder = [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments); Get-ChildItem $documentFolder;` – Richard Slater Oct 22 '14 at 19:11
  • Thanks a ton Richard the first method works. For educational purposes, could you perhaps explain why? Thanks a bunch. – ZEM Oct 22 '14 at 19:58
  • Sure thing - what specifically would you like me to explain? why splitting into two lines works? or why using $env:USERPROFILE works? – Richard Slater Oct 22 '14 at 20:08
  • Ok so, it seems your first method worked, but I tested with more users and still it seems that somehow the username is not being properly held as dynamic value when the script runs. I think its turning static somehow. I'm interested in how the join-path worked. – ZEM Oct 22 '14 at 20:33
  • I'm going to make a new question in a little while now that I have a better idea of what I'm asking for. – ZEM Oct 22 '14 at 20:35
  • Try adding some debuggability to the script. Add [CmdletBinding()] to the script, use the -Verbose parameter and then use write-verbose statements to output the values of the expression "C:\Users\$env:username\Documents" and more importantly whether that path is even valid. Then you can work out what it is about 'some' users and their profiles that makes the script fail. – Stephen Connolly Oct 22 '14 at 21:51