I am struggling with a bit of PowerShell, which I feel I should be able to do easily, and would appreciate some help.
I have a series of paths storing log and config files within C:\temp
. Not only that, but I need to delete the temp file and then create a symbolic link to the logged on user's OneDrive every time they run the app (which is launched with a batch file).
So I need it to run through about 10 folders such as
rmdir /Q /S c:\temp\app\cgi-bin
rmdir /Q /S c:\temp\app\contrib
rmdir /Q /S c:\temp\app\logs
etc.
...and then run the equivalent of:
mklink /D c:\temp\app\cgi-bin c:\users\<logged on user>\One Drive - Company Name\app\cgi-bin
mklink /D c:\temp\app\contrib c:\users\<logged on user>\One Drive - Company Name\app\contrib
mklink /D c:\temp\app\logs c:\users\<logged on user>\One Drive - Company Name\app\logs
What I have attempted in PS to do this is below:
$username = $env:username
(get-item C:\temp\app\cgi-bin).Delete()
New-item -ItemType SymbolicLink -path c:\temp\app\cgi-bin -target 'C:\users\$username\OneDrive - Company Name\app\cgi-bin\'
...and then was going to get it to run the same for each location:
$username = $env:username
(get-item C:\temp\app\contrib).Delete()
New-item -ItemType SymbolicLink -path c:\temp\app\contrib -target 'C:\users\$username\OneDrive - Company Name\app\contrib\'
etc.
...but have got completely lost. I feel there should be an easy way to loop through the original folder locations and then joining the parts together. I had another go with join-path
, but it didn't go too well either:
New-item -ItemType SymbolicLink -path C:\temp\app\cgi-bin -target (join-path 'C:\users' '"OneDrive - Company Name\app\cgi-bin\"')
Just, first, as you're new here -- so Welcome ! --, it doesn't really matter, but keep in mind to post the errors you are getting, because I had to figure them out here 😅.
Right, just a few things first :
foreach(){}
method.$env:onedrive
to get the current user's OneDrive directory ($env
is the environment variable, it's a preset system-wide variable basically containing user-useful settings)app
exists !$onedrive = "$env:onedrive - Company Name"
foreach ($folder in (Get-ChildItem -Path "C:\temp\app").Name){
Remove-Item -Path $folder
$onedrivePath = "$onedrive\app\$folder"
if (-not(Test-Path $onedrivePath)){
New-Item -ItemType Directory -Path $onedrivePath
}
New-item -ItemType SymbolicLink -Path "c:\temp\app\$folder" -target $onedrivePath
}
Feel free to comment if you want more explanations, and have a wonderful PowerShell journey (PowerShell is one of those incredible but underestimated languages...)
Silloky
EDIT :
After modifications to the script as you requested, here it is in all its beauty !
$onedrive = "$env:onedrive"
$pathArray = @(
"contrib",
"htdocs",
"install",
"licenses",
"locale",
"apache\logs",
"mysql\data",
"mysql\backup",
"perl",
"php",
"phpMyAdmin",
"sendmail",
"tmp",
"tomcat",
"webdav"
)
foreach ($path in $pathArray) {
$localpath = "c:\app\$path"
if (Test-Path $localpath) {
Remove-Item -path $localpath -Recurse -force -Confirm:$false
}
# Write-Output "Setting OneDrive Path"
$onedrivePath = "$onedrive\app\$path"
if (-not(Test-Path $onedrivePath)) {
New-Item -ItemType Directory -Path $onedrivePath
}
# Write-Output "Creating Junction"
New-item -ItemType Junction -Path "$localpath" -target $onedrivePath
}
I replaced Read-Host
by Write-Output
as it is more adequate : Read-Host
prompts for user input (like input()
in Python) when Write-Output
prints to the console (like print()
in Python), which is what you want assuming from the "prompt" texts.
I've also organised the array in much more semantic way, making it easier to edit.
Silloky