Network drives mapping from XP to 7 - windows

I am migrating multiple users from XP to 7 and they all have different mapped drives/locations on their current PC. After copying their all data from old PC to new PC, I am currently manually mapping their drives which consumes lot of time. Is there anyway of automating this process?
Is there any way of running a script on existing XP machine and running the same script on new Win 7 machine to map all the drives?
I am looking for a script or any other way of automating this process.
Thanks.

You could do this for all your users, it would at least tell you what they had.
you'd probably want one central folder, lets say Mappings, so try
net use > \servername\Mappings\%username%_map.txt
Or try something like this
http://www.visualbasicscript.com/List-mapped-drives-on-remote-machine-m28529.aspx

out of boredom i quickly wrote a powershell script to help you out.
Run this on your workstation:
(newpcs and oldpcs must be in correct order so oldpc1 is the old pc of the user of newpc1)
$oldpcs=#("oldpc1", "oldpc2", "oldpc3")
$newpcs = #("newpc1", "newpc2", "newpc3")
$mapping = #{}
for($i=0;$i -lt $oldpcs.Count; $i++){
$mapping.add($oldpcs[$i], $newpcs[$i])
}
foreach ($comp in $oldpcs){
$m = Get-WmiObject win32_systemnetworkconnections -ComputerName $comp
$m | %{
#i know this is not very elegant but whatever
$temp = $_.partcomponent -split "="
$temp = $temp -replace "`"", ""
$temp2= $temp[1] -split " "
$driveletter = $temp2[1] -replace "\(", ""
$driveletter = $driveletter -replace "\)", ""
$path = $temp2[0] -replace "\\\\", "\"
$f = "C:\path\to\folder\" + $mapping.$comp + ".txt"
Add-Content $f "$driveletter;$path"
}
}
Then get the file with corresponding computername to the new computer and run the following:
$txt = Get-Content "C:\path\to\file\$env:computername.txt"
$txt | % {
$temp = $_ -split ";"
net use $temp[0] $temp[1]
}
Remember that you have to run the mapping-script in the context of the user you want to map the drives for
Regards
P.S. Remotely mapping network drives is not possible afaik (i would love to be proven wrong)
You could create a logon script and map it to a user though

Related

Querying via powershell both 32bit and 64bit registry

I am running a script that queries windows and its registry.
I'm trying to add a code where it can query both 64bit and 32bit versions of the OS.
So if it's a 32bit then it should look at HKLM_SOFTWARE_TEAMVIEWER
and if it's 64bit it should query at HKLM_SOFTWARE_WOW6432Node_Teamviewer
So, how should this part look to query both locations depending on OS type?
$TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer").ClientID
This is the script:
Param(
[string]$ServerShare
)
$dom = $env:userdomain
$usr = $env:username
$Fullname = ([adsi]"WinNT://$dom/$usr,user").fullname
$TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer").ClientID
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version9").ClientID }
Apart from first detecting what bitness the computer uses, there is a simpler way I think by testing any of the two possible registry paths like:
# get the existing registry path (if any)
$regPath = 'HKLM:\SOFTWARE\TeamViewer', 'HKLM:\SOFTWARE\WOW6432Node\TeamViewer' | Where-Object { Test-Path -Path $_ }
if ($regPath) {
# we found the path, get the ClientID value
$TVID = (Get-ItemProperty -Path $regPath).ClientID
}
else {
Write-Warning "TeamViewer registry path not found"
}
You can check WMI under Win32_Processor and look at the process AddressWidth property to check your OS CPU AddressWidth.
#determine process version
[boolean]$is64bit = [boolean]((Get-WmiObject -Class "Win32_Processor" |
Where-Object {$_.DeviceID -eq 'CPU0'} | Select -ExpandProperty AddressWidth) -eq 64)
if ($is64bit){
#look here for 64 bit reg keys
Write-Output "x64 bit os detected"
}
else{
#look here for 32 bit reg keys
Write-Output " 32 bit os detected"
}
And run on my system
x64 bit OS Detected
Now all you need to do is merge your registry fetch code into the proper spots and you're on your way...
The easiest way to check OS bittness is to use .net.
[Environment]::Is64BitOperatingSystem

How to map Network Printers with PowerShell and CSV

I want to deploy our Network Printers that are shared from a Print-Server to Windows 10 PCs, on per-machine basis.
Currently we do this with a Kix-Script and ini file, but I want to move this to PowerShell and deploy it as a Startup/Login Script with Group Policy. The deployment must be with PowerShell not purely GPO, with a script we are more flexible to deploy to singular machines.
I've written a PS Script and using a CSV File containing the PCs and Printers to map, but it seams completely wrong. Is there a better way to deploy the printers?
Here are my CSV, 'True' is to set Printer as Default:
#TYPE Selected.System.Management.ManagementObject.Data.DataRow
Name
PC0001
\\SV0002\PR0001, True
\\SV0002\PR00002
Name
PC0002
\\SV0002\PR0001, True
\\SV0002\PR00002​
and the PS-Script:
Get–WMIObject Win32_Printer | where{$_.Network -eq ‘true‘} | foreach{$_.delete()}
$Printers=IMPORT-CSV \\server\$env:username\printers.csv
FOREACH ($Printer in $Printers) {
Invoke-Expression 'rundll32 printui.dll PrintUIEntry /in /q /n $($Printer.Name)'
}​
I edited the csv File, and it looks like this now:
Client;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;Default
PC0001;\\SV0001\PR0001;\\SV0001\PR0002;;;;;;;;;;;;;;pr_01
PC0002;\\SV0001\PR0001;\\SV0001\PR0002;\\SV0001\PR0003;;;;;;;;;;;;;pr_03
We did that with Excel, so it's easier to edit, and save it as csv.
Also where is located, we changed it to \Server\Netlogon\Subfolder\Printers.csv so that also the the Variable is changed to:
$Printers=IMPORT-CSV \\server\Netlogon\Subfolder\printers.csv
But now I think the whole script is wrong?
Using a CSV like this:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004
The code would be:
$csv = "\\server\Netlogon\Subfolder\printers.csv"
$Computers = Import-Csv $csv
foreach ($Computer in $Computers){
If ($Computer.name -eq $env:computername) {
$Printers = ($Computer.printers).split(";")
foreach ($Printer in $Printers) {Add-Printer $Printer -ErrorAction SilentlyContinue}
(New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)")
}
}
The way we do (did) it here at work was by invoking some VBScript from within the PowerShell script.
Print server and Printer are obtained via AD cmdlets.
$net = New-Object -Com WScript.Network
$net.AddWindowsPrinterConnection("\\" + $PRINT_SERVER + "\" + $PRINTER)
Starting from Windows 8 :
# Add the printer
Add-Printer -ConnectionName ("\\" + $printServer + "\" + $printerName) -Name $printerName
# Get the printer
$printer = Get-WmiObject -Query "Select * From Win32_Printer Where ShareName = '$printerName'"
# Set printer as default
$printer.SetDefaultPrinter()
I solved the Problem with the Script of James C., many thanks to him, it was a big help!.
The only wrong Thing was that between Add-Printer and $Printer, it had to be -ConnectionName. After that Little Edit in the script, everything was fine.
So we made a GP_Printers, where we putted under Computer Configuration/Windows Settings/Scripts/Startup this Script as printermapping.ps1
Also we putted into Shutdown a PowerShell Script where all Printer Connection are deleted.
Here are all the scripts.
CSV:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004
Printer Mappings with PowerShell depending on CSV:
$csv = "\\server\Netlogon\Subfolder\printers.csv"
$Computers = Import-Csv $csv
foreach ($Computer in $Computers){
If ($Computer.name -eq $env:computername) {
$Printers = ($Computer.printers).split(";")
foreach ($Printer in $Printers) {Add-Printer-ConnectionName $Printer -ErrorAction SilentlyContinue}
(New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)")
}
}
And the Printer Disconnection:
Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}
I hope this could be helpfoul for others.
Again many thanks to James C.
WBZ-ITS
I've made some correction and improvements to the script, and found also some Problem that Comes if you use it on a GPO, the changes are following:
CSV:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004
The Connection Script:
$csv = "\\server\Netlogon\Subfolder\printers.csv"
$Computers = Import-Csv $csv
foreach ($Computer in $Computers){
If ($Computer.name -eq $env:computername) {
$Printers = ($Computer.printers).split(";")
foreach ($Printer in $Printers) {Add-Printer-ConnectionName $Printer -ErrorAction SilentlyContinue}
(New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)")
}
}
And also a disconnect Script when logging off:
#$a = Get-WMIObject -query "Select * From Win32_Printer Where Name = 'Microsoft Print to PDF'"
#$a.SetDefaultPrinter()
$TargetPrinter = "Microsoft Print to PDF"
$ErrorActionPreference = “SilentlyContinue”
$LocalPrinter = GWMI -class Win32_Printer | Where {$_.Name -eq $TargetPrinter}
$LocalPrinter.SetDefaultPrinter()
$ErrorActionPreference = “Stop”
Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}
To disconnect the default printer must be changed, otherwise it won't be disconnected.
After all Script was made, we putted them in a GPO under User Configuration\Policies\Windows Settings\Scripts and there on Logon and Logoff.
You may have some troubles that the GPOs won't run, so here some usefull troubleshooting guides that i found:
The Scripts aren't working as Machine Policies under Startup and Shutdown, they have to be in the User Configuration as mentioned above.
Also you have to configure the Policie that deley the Script of 5 minutes. These are under Computer Configuration\Administrative Templates\System\Group Policy\Configure Logon Script Delay aktivate them and set the delay to 0 minutes, otherwise any Script will be deleyed to 5 minutes after logon.
Also a problem could be, if you are running the GPO on Windows 8/10 System, and you made them on a WIndows 7 PC. Create GPOs allways on the Server 2008/R2 or 2012R2 for this kind of system.
It could be helpfoul also if you configure the Logon/Logoff GPO as follows: As Scriptname "powershell.exe" (without quotes) and as Script Parameters -F "\SERVER\FREIGABE\meinskript.ps1" (with quotes.
I hope this could help someone else.
Thanks to who hleped me.
WBZ-ITS

Powershell/cmd to search content of all c$ hidden shares

Using "net view" I can view all the pcs on the network and browse their hidden shares \PC_NAME\c$ . But I can't find an easy way to search every pc on the network at once.
Is there a way using cmd/powershell to search for .pst .ost files on every machine in the network?
I want to use powershell or command prompt to automate it every few weeks.
You can use something like this:
$credentials = Get-Credential UsernameWithAccess
$servers = #("server1","server2")
foreach ($sever in $servers){
$shares = Get-WmiObject Win32_share -computer netdb -Credential $credentials
foreach ($path in $shares.name){
$content = Get-ChildItem -Recurse -path \\netdb\$path
$List = $content | where {$_.extension -eq ".dll"}
$List | format-table name
}
}
Make sure you change UsernamewithAccess with your user and servernames in second line, and extention from .dll to what you need to search for.

AWS Ec2 PowerShell userdata script extremely slow on boot

I'm currently starting a "Spot Instance" on the g2.xlarge CPU, and passing a startup script with the userdata paremeter Amazon has made available.
I want to move some files upon startup, from the root volume to the EBS volume. This is all perfect, and I have written a Powershell script to do this which runs just fine when I run the .ps1 file in a Remote Desktop Connected session from my mac. It takes just about 30 seconds to complete moving these files.
However!!! :) When I pass that EXACT SAME PowerShell script into the User-data upon creating the Spot Instance, it looks like it kinda freezes (it doesn't though, it's just slow) and it takes a whopping 10-20 minutes to finish moving the files! :/
Which means that the whole boot process is taking forever.
I have tried moving the files with robocopy, standard move commands and even the Powershell native Move-Item in a foreach loop. Same applies though: All the commands work just fine when being run from an RDP session, but when passed through the userdata upon launching the instance, to be run at boot, they are extremely slow to finish (or start?) :/
Does anyone know what the issue could be?
I really need the server to move the files automatically, and without having to RDP into the server to do it.
Thanks! :)
btw I'm running Windows Server 2012 R2
EDIT:
In case it has something to do with the script I use to move the files, here it is. :)
Start-Job -Name MoveFolder -ScriptBlock {
$path = "C:\Program Files (x86)\OldDestination"
$archpath = "Z:\NewDestination"
$counter = 0
$oldpercentage = 0
$files = Get-Childitem -Path $path -recurse -force
$totalcount = $files.count
$lasttime = [int][double]::Parse((Get-Date -UFormat "%s"))
foreach($file in $files) {
$filename = $file.FullName
Move-Item $file.FullName -destination $archpath -force -ErrorAction:SilentlyContinue
$counter++
$percentage = ($counter/$totalcount)*100
$percentage = [math]::Round($percentage)
if($percentage -gt 99) { $percentage = 99 }
$runtime = [int][double]::Parse((Get-Date -UFormat "%s"))
$runtime = $runtime - $lasttime
if($runtime -gt 5) { //Max. log process on server every > 5 seconds
if($percentage -gt $oldpercentage) {
Invoke-WebRequest -Uri http://exampleurl.com/$percentage -Method GET -UseBasicParsing
$lasttime = [int][double]::Parse((Get-Date -UFormat "%s"))
$oldpercentage = $percentage
}
}
}
$percentage = 100
Invoke-WebRequest -Uri http://exampleurl.com/$percentage -Method GET -UseBasicParsing
}
Wait-Job -Name MoveFolder

Powershell, How to get date of last Windows update install or at least checked for an update?

I am trying to find a way of retrieving the date/time of which the last windows update was either installed, or checked for.
So far I have found a function that allows to list recent Windows Updates, but it is far too much data and too bloated for such a simple function. Secondly I have tried to access the registry although I am having no luck in retriving the value I am after.
I am testing this on a Windows 10 Machine although the software will probably reside on Windows Server 2012 R2.
Here is an example of some of the code I have tried:
$key = “SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Install”
$keytype = [Microsoft.Win32.RegistryHive]::LocalMachine
$RemoteBase = [Microsoft.Win32.RegistryKey]::OpenBaseKey($keytype,"My Machine")
$regKey = $RemoteBase.OpenSubKey($key)
$KeyValue = $regkey.GetValue(”LastSuccessTime”)
$System = (Get-Date -Format "yyyy-MM-dd hh:mm:ss")
Also, just trying the Get-ChildItem
$hello = Get-ChildItem -Path “hkcu:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\”
foreach ($a in $hello) {
$a
}
I've checked in regedit and this key does not exist. Going to the "Windows Update" path shows only App Updates and not Windows updates.
EDIT
I seem to be closer to my goal with this line:
Get-HotFix | Where {$_.InstallDate -gt 30}
However how to I only retrive those of which have been installed in the last 30 days? And this doesnt show many results, even using Select $_.InstallDate
an option :
gwmi win32_quickfixengineering |sort installedon -desc
Another alternative, using the com object Microsoft.Update.Session can be find here : https://p0w3rsh3ll.wordpress.com/2012/10/25/getting-windows-updates-installation-history/
in short :
$Session = New-Object -ComObject Microsoft.Update.Session
$Searcher = $Session.CreateUpdateSearcher()
$HistoryCount = $Searcher.GetTotalHistoryCount()
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa386532%28v=vs.85%29.aspx
$Searcher.QueryHistory(0,$HistoryCount) | ForEach-Object {$_}
Here you have how to know the date and time of the last Windows update in a single line of Powershell:
(New-Object -com "Microsoft.Update.AutoUpdate"). Results | fl
You also have the following script to check it massively in Windows Server:
$ servers = Get-ADComputer -Filter {(OperatingSystem-like "* windows * server *") -and (Enabled -eq "True")} -Properties OperatingSystem | Sort Name | select -Unique Name
foreach ($ server in $ servers) {
write-host $ server.Name
Invoke-Command -ComputerName $ server.Name -ScriptBlock {
(New-Object -com "Microsoft.Update.AutoUpdate"). Results}
}
Extracted from: https://www.sysadmit.com/2019/03/windows-update-ver-fecha-powershell.html
Get-HotFix |?{$_.InstalledOn -gt ((Get-Date).AddDays(-30))}
Using PowerShell, you can get the date of the las Windows update like this:
$lastWindowsUpdate = (Get-Hotfix | Sort-Object -Property InstalledOn -Descending | Select-Object -First 1).InstalledOn

Resources