PowerShell: Using $env:userprofile in an 'IF' statement - powershell

I am using PowerShell ISE (I think 4).
I am writing logon scripts to replace the old '*.BAT' files.
I am trying to test for a user-profile condition before 'creating/deleting' certain directories from the desktop.
Example
If(($env:userprofile = "rmullins"))
{
Remove-Item $env:userprofile\Desktop\ITFILES -Recurse -Force
}
So I run the following to see what's going on:
md -Path $env:userprofile\Desktop\ITFILES
The path is created in the following location:
C:\Windows\System32.........
The MD command above works fine until I run that 'IF' statement. I think I might not understand how the $env:userprofile part works.
Any ideas?

On Windows 7:
[PS]> echo $ENV:UserProfile
C:\Users\arco444
This returns the path to the profile directory. Therefore I'd expect looking only for the username to fail the condition. I'd do a simple match instead:
if ($env:userprofile -imatch "rmullins")
{
Remove-Item $env:userprofile\Desktop\ITFILES -Recurse -Force
}

Related

Test-Path Remove-Item issue

I have a powershell script to install a very large application (15gb source media) from a location its been delivered to on the C drive.
At the end of the script, to ensure that the software is installed I perform a test-path of the HKLM Microsoft Windows CurrentVersion Uninstall path for the GUID, and if successful, clear the source media from the C drive.
If (Test-Path("HKLM:pathname")) { Remove-Item $path -force -recurse }
The problem I have is that the above command works via Powershell ISE when run individually. It knows the key exists so should perform Remove-Item. When run as a script, or via a deployment mechanism, it will not remove the folder.
I have even gone further and used:
GCI $Path -Recurse | Remove-Item -force -recurse
... to no avail.
Prior to introducing the Test-Path, I only had the Remove-Item $Path -force -recurse and this worked!!
So despite Test-Path correctly judging, it appears to prevent Remove-Item from doing anything. (I wrote to a log file to check the If routing)
Any thoughts? Sorry for any typos, I did not copy / paste any part of the script.
If you can't delete the key immediately after, that probably means it has a write lock that's been applied by the Test-Path cmdlet.
Try finding out if a lock exist using Sysinternals Handle command and then release it using the handle.exe -c argument, referencing the hexadecimal number.
Make sure the format used in $path matches the format used by handle.exe
$lock = & handle.exe -nobanner -a -p ($PID) ($path)
if (-not ($lock -like '*No matching handles found*')){
& handle.exe -nobanner -p ($PID) -c ($lock[0].split(':')[0].Trim(' ')) -y
}
This will only work if you have the permission to close handles.

$PSScriptRoot NULL value - recursive deletion

I had an issue with one of my scripts that has a few calls to Remove-Item, here are all of them:
Remove-Item -r -force "$path_Docs\*"
Remove-Item -recurse -force ( join-path $PSScriptRoot "\logs\*" ) | Out-Null
Remove-Item -r -force "$MappingFilePath\*
These variables are set to:
$MappingFilePath = ( Join-Path $PSScriptRoot "\Table Mappings\")
$path_Docs = (join-path $settings.files.data_folder "\documents")
Basically what happened is, I started my script which is a schema migration script and takes around 3 hours for the database I was running it on. Went on lunch, came back and saw that my script had decided to try and recursively delete the entire C:\ drive. I can't think of any reason as to why this would have happened other than $PSScriptRoot being NULL, but then again i always Set-Location to the script root directory before running the script so i am not entirely sure.
Either way i have added the following to the top of my script main and ran it again a few times without issue:
## NOT AGAIN!!!
if ([string]::IsNullOrEmpty($PSScriptRoot)) {
Set-Output "[!!!] Dodged a bullet on this one" -colour red -logfilepath $log_prerequisites
break;
}
And changed all Remove-Item calls to have a filter:
Remove-Item -r -force "$MappingFilePath\*.xlsx"
Remove-Item -recurse -force "$PSScriptRoot\logs\*.log" | Out-Null
Is using $PSScriptRoot the best way of getting the script directory and if not what other methods are there? and how could the usage of the above commands have resulted in a recursive deletion of C:\?
Duplication Edit: This is less about the usage of $PSScriptRoot and more about how the recursive deletion could have happened.

Get-ChildItem Stop Script if Filetype within a folder did not exists

I am trying to handle some "Errors" in my PowerShell script. If a specific file type (.key) does not exist in a specified folder, there is nothing to do for the script, so it should terminate. I use this sample to solve my problem, which does not work as expected. PowerShell did not terminate.
$Eventlogfolder = "c:\temp\test\"
# Check if subfolder exists and check if .key-files are available in this folder.
# if not - exit. There is nothing to do if no LicenceFile (*.key Files) are available.
$CheckFileExistence = Get-ChildItem $EventLogFolder -recurse -filter "*.key"
if (!($CheckFileExistence)) {ErrorAction Stop}
What I know is, the Get-ChildItem gives an empty array as a result. There is no error-message or status. I assume that's why ErrorAction did not work here.
So my question is, how do I exit from Get-ChildItem ? When I use EXIT the PowerShell ISE exits.
Something like this?
$Eventlogfolder = "c:\temp\test\"
$CheckFileExistence = Get-ChildItem $EventLogFolder -recurse -filter "*.key"
if ([string]::IsNullOrEmpty($CheckFileExistence)){
throw "No .key files found in $Eventlogfolder"
}else{
# do stuff with .key files
}

Powershell: Setting SASS_BINARY_PATH

I need to set SASS_BINARY_PATH environment variable with the local file I've downloaded to be able to install node-sass behind a corporate firewall. So on windows cmd, I just do:
SET SASS_BINARY_PATH=C:\Source\Repos\SRT\Srt.Web\sass-binary\v4.7.2\win32-x64-48_binding.node
And the installation works fine since it successfully sets the variable. But when I try doing it via Powershell, it doesn't work:
$env:SASS_BINARY_PATH="C:\Source\Repos\SRT\Srt.Web\sass-binary\v4.7.2\win32-x64-48_binding.node"
I've also tried another way on Powershell:
[Environment]::SetEnvironmentVariable("SASS_BINARY_PATH", "C:\Source\Repos\SRT\Srt.Web\sass-binary\v4.7.2\win32-x64-48_binding.node", "Machine")
Upon checking it on the control panel, it successfully added a "SASS_BINARY_PATH" system variable. But upon trying to reinstall node-sass, it fails again.
One of my observations is when I'm doing it the windows cmd way then check it by using the command line set, the variable shows up along with others. But when I use both the Powershell methods, it does not show up. Any ideas on this?
The error encountered when trying to npm-install node-sass over a corporate firewall is:
Downloading binary from
https://github.com/sass/node-sass/releases/download/v4.7
.2/win32-x64-48_binding.node Cannot download
"https://github.com/sass/node-sass/releases/download/v4.7.2/win3
2-x64-48_binding.node":
HTTP error 401 Unauthorized
Download win32-x64-48_binding.node manually
Put it in C:\Users\<user>\AppData\Roaming\npm-cache\node-sass\4.7.2 folder.
Then try to run npm install node-sass
here is the PowerShell command #jengfad used based on above solution which is commented in the discussion
$cacheSassPath = $env:APPDATA + '\npm-cache\node-sass'
if( -Not (Test-Path -Path $cacheSassPath ) )
{
Write-Host "cacheSassPath not exists"
New-Item -ItemType directory -Path $cacheSassPath
Write-Host "cacheSassPath CREATED"
}
<# Ensure has no content #>
Get-ChildItem -Path $cacheSassPath -Recurse| Foreach-object {Remove-item -Recurse -path $_.FullName }
<# Copy local sass binary (~Srt.Web\sass-binary\4.7.2) file to cache folder #>
$sassBinaryPath = split-path -parent $MyInvocation.MyCommand.Definition
$sassBinaryPath = $sassBinaryPath + "\sass-binary\4.7.2"
Copy-Item -Path $sassBinaryPath -Recurse -Destination $npmcachedir -Container
Write-Host "node-sass binary file successfully copied!"

Power shell script for copying files with a specific name and a specific extension to a folder from where the script is executing

All,
My intention is to copy all the files with starting with the name 'US.Services' and with the extension .dll from a directory and its sub directories to the place where the script is being executed, i have the following but nothing gets copied. Any help would be appreciated.
Get-Childitem -Path ".\.\" -Filter *US.Services*.dll -Recurse |
Copy-Item -Destination "."
Thanks -Nen
Since PowerShell v3 can use the $PSScriptRoot automatic variable to refer to the location where the script is saved (in PowerShell v2 that would be $here = $MyInvocation.MyCommand.Path | Split-Path.
Be aware the both those approaches work only when the script is executed, if you just paste them to PowerShell console they won't return any value.
If I understand your question correctly you look for files that start with the given string and end with the extension, so you need to use the * wildcard here: US.Services*.dll.
Get-Childitem -Path $PSScriptRoot -Recurse -Filter "US.Services*.dll" |
Copy-Item -Destination $PSScriptRoot
This will likely produce exceptions if there are files with the same name copied to the single directory, as two files cannot be named the same within single directory.