Insert Username in to file path Powershell - powershell

We are in the process of trying to tidy up our users home directories and speed up some office 2007 performance by moving all their templates in to a new directory on their user drive (U:). During my initial tests I can get the below script to work fine though it has the obvious problem of only working for my username. Is there a way to get it to take the currently logging in user? Before this would be handled by %username% and from a brief scan of the internet apparently:
$[Environment]::UserName
Should work. However I seem to be getting errors. Is there a better way to achieve the current logging in users name in to the file path?
if (!(Test-Path -path '\\SERVER\PATH\TO FILES\$[Environment]::UserName\Normal\'))
{
New-Item '\\SERVER\PATH\TO FILES\$[Environment]::UserName\Normal\' -type directory
##Move-Item \\SERVER\PATH\TO FILES\$env:username\Normal.dot \\\SERVER\PATH\TO FILES\$env:username\Normal\
## Move-Item \\SERVER\PATH\TO FILES\$env:username\*.dotm \\SERVER\PATH\TO FILES\%username%\Normal\
}
else
{
"No work to do"
}

Two problems. If you want variable/expression substitution to take place in a string, you need to use quotation-marks, not apostrophes, to enclose the string. In this case, you also need to add some parenthesis to denote an expression within the string.
"\\SERVER\PATH\TO FILES\$([Environment]::UserName)\Normal\"

Related

Powershell: Rename a folder when only partial name is known

I need to rename a folder without knowing the full folder name.
For Example C:\myfolder-2021-5-1 (I know the first part of the folder name)
I would like to rename it to c:\myfolder... Again, the script wont always know the full folder name.
Edit: I am new to Powershell. I have spent a few hours looking on Google and I don't see examples of people trying to rename a folder using a wildcard. There are very few folder renaming examples that I could find. Most of what I find pertains to renaming files not folders.
I get it people wanting me to "try" first and then ask questions. But, sometimes, especially for us newbies, we don't even know where to start.
I tried using several filename examples and just using a directory name with a wildcard and that did not work.
Don't know what else to say.
Any ideas?
Thanks!
You cant rename a directory if you dont know it's name - thats just not how files and directories work. What you can do is search for a directory that matches your criteria, then you can rename it.
(I'm assuming the reason you dont know the exact name is because its a date, but im also assuming the format of the directory name is consistent)
At its most basic level, this would work for your example:
get-childitem -Path c:\ -Directory -Filter "myfolder-????-*-*" | Move-Item -Destination "renamed-myfolder"
This will search for directories in C:\ that match the pattern "myfolder-????-*-*" - so this pattern would match your example folder C:\myfolder-2021-5-1. Then pass that Directory down the pipeline (|) into Move-Item where the directory is renamed to c:\renamed-myfolder.
This code has some major drawbacks though! It doesnt check if the new name exists before trying to rename the directory so it might fail. Also if more than 1 folder matches the filter only the first rename (Move-Item) will succeed. Its upto you to think about these edge cases and add suitable logic to detect/prevent them.
Its a good idea to use Test-Path command to check if the destination name already exists or not:
if(Test-Path -Path c:\renamed-myfolder){
throw "ERROR - c:\renamed-myfolder already exists!";
}
NOTE: Get-ChildItem filters * means "any characters" and ? means "one character" so "myfolder-*-*-*" would also work, but if the year is always 4 digits then use the ???? as its more specific. Ive used the filter "myfolder-????-*-*" as im assuming some days/months will be 2 digits like myfolder-2021-12-12.

Start process using wildcard for drive letter

I have a file which will always be located on a users desktop, however, depending on how the machine was set up, the desktop could be located on the C drive or D drive.
Below is what I have tried to use. On it's own, (Get-Location).Drive.Name will return the C drive on my machine. However, if I combine it into the full line of code to start the program, it does not work.
What am I doing wrong?
$userName = [Environment]::UserName
Start-Process ((Get-Location).Drive.Name)\Users\$($userName)\Desktop\VIPHorizon\Service_Desk.url
While the other answer is correct that you are missing a colon, simply adding that is not sufficient.
If you try running it with the colon, you will get another error like so:
Unexpected token ':\Users' in expression or statement.
In order to fix this, you need to wrap the whole thing in quote marks.
"((get-location).Drive.Name):\Users\$($userName)\Desktop\VIPHorizon\Service_Desk.url"
Then you will find that the ((get-location).Drive.Name) is written directly into the string, instead of being replaced. which can be fixed by prefixing the call with a dollar sign like you have already done for userName.
"$((get-location).Drive.Name):\Users\$($userName)\Desktop\VIPHorizon\Service_Desk.url"
You need to put a colon ( : ) right after your drive letter:
$userName = [Environment]::UserName
Start-Process ((get-location).Drive.Name):\Users\$($userName)\Desktop\VIPHorizon\Service_Desk.url
The proper way to get current users Desktop even if relocated is:
[Environment]::GetFolderPath('Desktop')
So use:
Start-Process (Join-Path [Environment]::GetFolderPath('Desktop') "VIPHorizon\Service_Desk.url")
To eumerate all special folders and current settings:
$SpecialFolders = [Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])|Sort
ForEach ($SpecialFolder in $SpecialFolders) {
[PSCustomObject]#{
SpecialFolderName = $SpecialFolder
SpecialFolderLocation = ([Environment]::GetFolderPath($SpecialFolder))
}
}
The global Powershell variable $HOME will give you the home location for the active user.
Start-Process $HOME\Desktop\VIPHorizon\Service_Desk.url

Get all references to a given PowerShell module

Is there a way to find a list of script files that reference a given module (.psm1)? In other words, get all files that, in the script code, use at least 1 of the cmdlets defined in the module.
Obviously because of PowerShell 3.0 and above, most of my script files don't have an explicit Import-Module MODULE_NAME in the code somewhere, so I can't use that text to search on.
I know I can use Get-ChildItem -Path '...' -Recurse | Select-String 'TextToSearchFor' to search for a particular string inside of files, but that's not the same as searching for any reference to any cmdlet of a module. I could do a search for every single cmdlet in my module, but I was wondering if there is a better way.
Clarification: I'm only looking inside of a controlled environment where I have all the scripts in one file location.
Depending on the scenario, the callstack could be interesting to play around with. In that case you need to modify the functions which you want to find out about to gather information about the callstack at runtime and log it somewhere. Over time you might have enough logs to make some good assumptions.
function yourfunction {
$stack = Get-PSCallStack
if ($stack.Count -gt 1) {
$stack[1] # log this to a file or whatever you need
}
}
This might not work at all in your scenario, but I thought I throw it in there as an option.

Check for File in multiple directories with an IF statement Powershell

I am facing some problems in powershell. I want to be able to let a powershell command search for multiple directories.
With the name being a variable like "$VM_DISK=VM_DISK.vhdx" and let powershell search in that manor so that if that file exists in a folder such as C:\VM_DISK\ it exit the script.
I have already tried the "Get-Childitem" but it doesn't seem to work when I put my variable in it. Here is an example:
$VM_DISK= "Example.vhdx"
$search=Get-ChildItem -Path C:\VM_DISK\* -Filter $VM_DISK -Recurse
if ($search -eq $VM_DISK) {write-host "Goodbye!" exit} else {write-host "Continue"}
I just cant seem to figure out why this isn't working, hope some can figure it out.
You need to alter your if statement.
if ($search.Name -contains $VM_Disk)
This way you are comparing an Array of names (which is what you want, names of objects, not objects) to a name of particular object (to a string, basically).
This makes little sense in your case, tbh. Since $search would always include $VM_Disk or would be null if nothing was found.
So the proper way to test would be if ($search) (just like Mathias advised). Which would test if anything was returned. Which, basically equals what you are trying to do.

preplog.exe ran in foreach log file

I have a folder with x amount of web log files and I need to prep them for bulk import to SQL
for that I have to run preplog.exe into each one of them.
I want to create a Power script to do this for me, the problem that I'm having is that preplog.exe has to be run in CMD and I need to enter the input path and the output path.
For Example:
D:>preplog c:\blah.log > out.log
I've been playing with Foreach but I haven't have any luck.
Any pointers will be much appreciated
I would guess...
Get-ChildItem "C:\Folder\MyLogFiles" | Foreach-Object { preplog $_.FullName | Out-File "preplog.log" -Append }
FYI it is good practice on this site to post your not working code so at least we have some context. Here I assume you're logging to the current directory into one file.
Additionally you've said you need to run in CMD but you've tagged PowerShell - it pays to be specific. I've assumed PowerShell because it's a LOT easier to script.
I've also had to assume that the folder contains ONLY your log files, otherwise you will need to include a Where statement to filter the items.
In short I've made a lot of assumptions that means this may not be an accurate answer, so keep all this in mind for your next question =)