halbaradkenafin Posted September 25, 2015 Posted September 25, 2015 This is a thread for all those questions about Powershell that you can't quite figure out yourself or that Google just isn't helping with. 3
3s-gtech Posted September 25, 2015 Posted September 25, 2015 Save a folder full of Word documents directly to PDF without having to open each one or use an online tool. Change or # $File or $Files as appropriate. # Acquire a list of DOCX files in a folder #$File= "C:\Foofolder\foofile.docx" $Files=GET-CHILDITEM "\\server\share\folder of word docs\*.DOCX" $Word=NEW-OBJECT –COMOBJECT WORD.APPLICATION Foreach ($File in $Files) { # open a Word document, filename from the directory $Doc=$Word.Documents.Open($File.fullname) # Swap out DOCX with PDF in the Filename $Name=($Doc.Fullname).replace("docx","pdf") # Save this File as a PDF in Word 2010/2013 $Doc.saveas([ref] $Name, [ref] 17) $Doc.close() } 3
Geoff Posted September 25, 2015 Posted September 25, 2015 Get the Windows Product Key of a specified machine via WMI. function get-windowsproductkey([string]$computer) { $Reg = [WMIClass] ("\\" + $computer + "\root\default:StdRegProv") $values = [byte[]]($reg.getbinaryvalue(2147483650,"SOFTWARE\Microsoft\Windows NT\CurrentVersion","DigitalProductId").uvalue) $lookup = [char[]]("B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9") $keyStartIndex = [int]52; $keyEndIndex = [int]($keyStartIndex + 15); $decodeLength = [int]29 $decodeStringLength = [int]15 $decodedChars = new-object char[] $decodeLength $hexPid = new-object System.Collections.ArrayList for ($i = $keyStartIndex; $i -le $keyEndIndex; $i++){ [void]$hexPid.Add($values[$i]) } for ( $i = $decodeLength - 1; $i -ge 0; $i--) { if (($i + 1) % 6 -eq 0){$decodedChars[$i] = '-'} else { $digitMapIndex = [int]0 for ($j = $decodeStringLength - 1; $j -ge 0; $j--) { $byteValue = [int](($digitMapIndex * [int]256) -bor [byte]$hexPid[$j]); $hexPid[$j] = [byte] ([math]::Floor($byteValue / 24)); $digitMapIndex = $byteValue % 24; $decodedChars[$i] = $lookup[$digitMapIndex]; } } } $STR = '' $decodedChars | % { $str+=$_} $STR } get-windowsproductkey . 1
sted Posted September 25, 2015 Posted September 25, 2015 # system info ps v1 #locate output file & define default values $filepath="[url="file://\\server\inventory2$\outputfile.csv"]\\server\inventory2$\outputfile.csv[/url]" $dop="-" $warantyyears="-" $warantyend="-" $location = "-" $file="" $csvout="" $arrayloc="" $newline="" #import existing file if it exists if(test-path -path $filepath) { $fileexists="true" $file = Import-Csv $filepath } if(!(test-path -path $filepath)) { $fileexists="false" } # get mac address active cards (tested on multinics) $mac= Get-WmiObject Win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"' | Select macAddress if ($mac.count) {$mac3=$mac.macaddress[0] + " : " + $mac.macaddress[1]} else {$mac3=$mac.macaddress} # get processor and pc name $procinfo = Get-WmiObject Win32_Processor $cpuname=$procinfo.Name $pcname=$procinfo.SystemName # get memory info/model/make $pcinfo = Get-WmiObject Win32_ComputerSystem $maker=$pcinfo.Manufacturer $model=$pcinfo.Model $ram=$pcinfo.TotalPhysicalMemory/1024/1024/1024 $ram = "{0:N1}" -f $ram #get serial no $serial=Get-WmiObject Win32_BIOS $serial2=$serial.SerialNumber #hdd size and free in gb rounded to nearest whole no $hdddata=Get-WmiObject Win32_LogicalDisk -Filter 'deviceid="c:"' $freespace=$hdddata.FreeSpace/1024/1024/1024 $freespace = "{0:N0}" -f $freespace $totalspace=$hdddata.size/1024/1024/1024 $totalspace = "{0:N0}" -f $totalspace # get windows version $os=Get-WmiObject Win32_OperatingSystem | select caption $os2=$os.caption #date-time $now= Get-Date $now2 = $now.date #create csv data if no existing file if ($fileexists -eq "false") { #echo "new file created" $csvout = New-Object psobject $csvout | add-member NoteProperty Macaddress $mac3 $csvout | add-member NoteProperty PCName $pcname $csvout | add-member NoteProperty Manufacturer $Maker $csvout | add-member NoteProperty "PC Model" $model $csvout | add-member NoteProperty Processor $CPUName $csvout | add-member NoteProperty Memory $ram $csvout | add-member NoteProperty "HDD Size" $totalspace $csvout | add-member NoteProperty "HDD Free" $freespace $csvout | add-member NoteProperty "Serial No" $serial2 $csvout | add-member NoteProperty "Windows Version" $os2 $csvout | add-member NoteProperty "Date Collected" $now2 $csvout | add-member NoteProperty "Date purchased" $dop $csvout | add-member NoteProperty "Warranty years" $warantyyears $csvout | add-member NoteProperty "Warranty Expiration" $warantyend $csvout | add-member NoteProperty "Location" $location $csvout | export-csv $filepath -notypeinformation #-Append } if($fileexists -eq "true") { $arrayloc=[array]::indexof($file.pcname, $pcname) if (!($arrayloc -eq -1)) { #echo "replacing data" #$file[$arrayloc] |Format-Table $file[$arrayloc].macaddress=$mac3 $file[$arrayloc].pcname= $pcname $file[$arrayloc].Manufacturer=$maker $file[$arrayloc]."pc model"=$model $file[$arrayloc].processor=$cpuname $file[$arrayloc].memory=$ram $file[$arrayloc]."hdd size" = $totalspace $file[$arrayloc]."hdd free" = $freespace $file[$arrayloc]."serial no" = $serial2 $file[$arrayloc]."Windows Version" = $os2 $file[$arrayloc]."Date Collected" = $now2 $file | export-csv $filepath -notypeinformation } if ($arrayloc -eq -1) { #echo "adding new line" $csvout = New-Object psobject $csvout | add-member NoteProperty Macaddress $mac3 $csvout | add-member NoteProperty PCName $pcname $csvout | add-member NoteProperty Manufacturer $Maker $csvout | add-member NoteProperty "PC Model" $model $csvout | add-member NoteProperty Processor $CPUName $csvout | add-member NoteProperty Memory $ram $csvout | add-member NoteProperty "HDD Size" $totalspace $csvout | add-member NoteProperty "HDD Free" $freespace $csvout | add-member NoteProperty "Serial No" $serial2 $csvout | add-member NoteProperty "Windows Version" $os2 $csvout | add-member NoteProperty "Date Collected" $now2 $csvout | add-member NoteProperty "Date purchased" $dop $csvout | add-member NoteProperty "Warranty years" $warantyyears $csvout | add-member NoteProperty "Warranty Expiration" $warantyend $csvout | add-member NoteProperty "Location" $location $csvout | export-csv $filepath -notypeinformation -Append } } grabs pc system info and dumps to a csv file be aware that every now and again the file gets blanked out and nothing writes to it until you restore/delete it but it never does it when I test so ive not managed to track down exactly why I suspect too many pcs trying to run it at once
Geoff Posted September 25, 2015 Posted September 25, 2015 Which reminds me, this script will get the last login user and the basic system details and update the computer description in AD. If you run this as a login script you will need to give authenticated users access to update the description field on computer objects. Set WshNetwork = WScript.CreateObject("WScript.Network") Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") ' Get service tag and computer manufacturer For Each objSMBIOS in objWMI.ExecQuery("Select * from Win32_SystemEnclosure") serviceTag = replace(objSMBIOS.SerialNumber, ",", ".") manufacturer = replace(objSMBIOS.Manufacturer, ",", ".") Next ' Get computer model For Each objComputer in objWMI.ExecQuery("Select * from Win32_ComputerSystem") model = trim(replace(objComputer.Model, ",", ".")) Next ' Get computer object in AD Set objSysInfo = CreateObject("ADSystemInfo") Set objComputer = GetObject("LDAP://" & objSysInfo.ComputerName) ' Build up description field data and save into computer object if different from current description ' We also do not update computers with a description that starts with an underscore (_) newDescription = WshNetwork.UserName & " (" & serviceTag & " – " & manufacturer & " " & model & ")" if not objComputer.Description = newDescription and not left(objComputer.Description,1) = "_" then objComputer.Description = newDescription objComputer.SetInfo end if
Knil92 Posted March 17, 2016 Posted March 17, 2016 CD C:\filepath\folderwithfiles\torename Dir | Rename-Item –NewName { $_.name –replace “what you want to replace“,”what you want it to be replaced to” } These two lines allow you to batch rename files. We used this as a school we support used a photographer that put the class name and the pupils admission number. We only wanted the admission number as the file name, so we used this to replace the class name with nothing. Maybe some one can add something extra like a counter to it so that you could use it to change the file name to something like filename001, filename002 etc... Just to make it a bit more useful
mikeyd101 Posted March 17, 2016 Posted March 17, 2016 Get active directory objects via LDAP (doesn't require AD modules) function Get-ADObjects{ param ( $searchroot = [system.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain(), $Category = "(objectCategory=computer)", $fieldlist = @("name", "cn") ) $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = "LDAP://$searchroot" $objSearcher.Filter = ($Category) $objSearcher.SearchScope = "subtree" $objSearcher.pagesize = 10000 # TODO: request / consolidate from all domain controllers foreach ($i in $fieldlist) { $temp = $objSearcher.PropertiesToLoad.Add($i) } $colResults = $objSearcher.FindAll() $Results = @() foreach ($objResult in $colResults) { $Result = New-Object PSObject foreach ($Property in $objResult.Properties.getenumerator()) { if($Property.Value) { $Result | Add-Member NoteProperty $Property.Key ([string]$Property.Value) } } $Results += $Result } $Results } 1
vascodagama Posted November 29, 2016 Posted November 29, 2016 $CurrScheme = (powercfg -getactivescheme) $AllSchemes = (powercfg -list) If ($CurrScheme -like '*CustomPowerPlan*') { Exit} IF ($AllSchemes -like '*CustomPowerPlan*') { set-powerplan "CustomPowerPlan" Exit } Else { Powercfg -import C:\Users\User\Documents\CustomPowerPlan.pow start-sleep -milliseconds 500 set-powerplan "CustomPowerPlan" } This simple script imports and applies a custom powerplan. I know this can be done through Group policy but I found this added a large amount of time to pc login. This is my first powershell script, any advice is appreciated
rsaddul1 Posted June 7, 2017 Posted June 7, 2017 (edited) Hello, I am very new to Powershell hope someone can help. I hope you can help with the below bit of code? For some reason, it does not show the two files copied successfully. Instead, it tells me all files did not copy ok. The error message is shown below: copy : Illegal characters in path. At C:\Users\rsaddul1.318\Desktop\log.ps1:20 char:1 + copy $_.fullname $destination -Force -Recurse -errorAction silentlyCo ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (http://awscdn.cdngeek.com/images/smilies/smile.png [Copy-Item], ArgumentException + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Comm ands.CopyItemCommand My Script is below: # Moves latest two filesGet-ChildItem 'C:\scripts' -File |Sort-Object -Property CreationTime -Descending |Select-Object -Last 2 |Copy-Item -Destination 'C:\TEST' -Force # Delete all Files in C:\temp older than 365 day(s) $Path = "C:\scripts" $Daysback = "-365" $CurrentDate = Get-Date $DatetoDelete = $CurrentDate.AddDays($Daysback)Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } |Remove-Item -WhatIF # Creates Log File $logProgress = 'C:\scripts\scriptlog.log' $source = 'C:\scripts\*.txt' $destination = 'C:\TEST\*.txt' get-childitem $source -recurse | foreach {copy $_.fullname $destination -Force -Recurse -errorAction silentlyContinueif($? -eq $false){echo "$($_.fullname) did not copy ok to $destination" | out-file -append $logProgress} else {write-output "$($_.fullname) copied OK to $destination" | out-file -append $logProgress} } Edited June 7, 2017 by rsaddul1
steve Posted June 7, 2017 Posted June 7, 2017 Its a little difficult to make out your code as the format is corrupt. But from what I can make out, the first probelm is the line: $destination = 'C:\TEST\*.txt' Is the issue, you're specifying a destination folder but have a wildcard for text files in there too. Try $destination = 'C:\TEST\' This works, but not sure if its what you were trying to do: # Moves latest two files Get-ChildItem 'C:\scripts' -File | Sort-Object -Property CreationTime -Descending | Select-Object -Last 2 | Copy-Item -Destination 'C:\TEST' -Force $Path = "C:\scripts" $Daysback = "-365" $CurrentDate = Get-Date $DatetoDelete = $CurrentDate.AddDays($Daysback) Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item -WhatIF # Creates Log File $logProgress = 'C:\scripts\scriptlog.log' $source = 'C:\scripts\*.txt' $destination = 'C:\TEST' $txtfiles = get-childitem $source -recurse | Select-Object FullName foreach ($file in $txtfiles) {Move-Item -Path $file.FullName -Destination $destination -Force -ErrorAction SilentlyContinue if($? -eq $false){Write-Output "$($file.FullName) did not copy ok to $destination" | out-file -append $logProgress} else {write-output "$($file.FullName) copied OK to $destination" | out-file -append $logProgress} }
rsaddul1 Posted June 9, 2017 Posted June 9, 2017 Thanks so much. You have resolved this so promptly! I'm going to be cheeky now and ask if you know what code to add to send the log file in an email? Thanks Rsaddul
rsaddul1 Posted June 9, 2017 Posted June 9, 2017 However, it does copy all files, which is an issue. The code at the top is supposed to copy the two latest files. It seems that the bottom code is affecting it and copying everything now?
howartp Posted June 9, 2017 Posted June 9, 2017 As Steve says, your code was messed up and thus confusing. What are you trying to achieve in layman's terms? Your original script you posted did this: 1) Copied 2 newest files from Scripts to Test 2) Deleted any files in Scripts older than 365 days 3) Copied all txt files from Scripts to Test What do you want it to do then one of us can fix it for you.
rsaddul1 Posted June 9, 2017 Posted June 9, 2017 Sorry for the confusion. I am trying to achieve the below: 1) Copy 2 newest files from Scripts to Test and show this in a log. The log must show if has failed or been a success. This log to be sent in an email. 2) Deleted any files in Scripts older than 365 days Thanks RS
rsaddul1 Posted June 13, 2017 Posted June 13, 2017 Hi Guys, Was wondering if there was any update howartp or steve Thanks
Knil92 Posted June 13, 2017 Posted June 13, 2017 why not just copy the two files and then delete everything in the other folder?
steve Posted June 13, 2017 Posted June 13, 2017 I've had a look at what you asked for. I think this covers it, but I can't test the email stuff from home. This copies (not moves) the 2 files of any type that were most recently created in the scripts folder - note this may include the log file it creates. #Define the variables needed $Path = "C:\scripts" #folder where files are $NumberOfFiles = "2" #Number of files to move $Destination = 'C:\test' #Destination of files being moved $Daysback = "-365" #Minimum age of files to delete $CurrentDate = Get-Date #Todays date $DatetoDelete = $CurrentDate.AddDays($Daysback) #calculate the date before which to delete files $logProgress = 'C:\scripts\scriptlog.log' #name of log file #email variables $Subject = "File copy" + $CurrentDate $SMTPServer = "your.mailserver" $Sender = "[email protected]" $Recipients = "[email protected]", "[email protected]" #Get a list of the last 2 files to be created, change -first to -last if you want the oldest $FilesToMove = Get-ChildItem -Path $Path -File | Sort-Object -Property CreationTime -Descending | Select-Object -First $NumberOfFiles | Select-Object -Property FullName #Copy the files to new destination Foreach ($file in $FilesToMove) {Copy-Item -Path $file.FullName -Destination $destination -Force -ErrorAction SilentlyContinue #copy each file if($? -eq $false){Write-Output -InputObject "$($file.FullName) did not copy ok to $destination" | out-file -FilePath $logProgress -appends} #if it fails write error else {write-output -InputObject "$($file.FullName) copied OK to $destination" | out-file -FilePath $logProgress -append } #if ok, write ok } #Send the log as an email in the body Send-MailMessage -From $Sender -To $Recipients -Subject $Subject -Body (Get-Content -Path $logProgress | Out-String) -SmtpServer $SMTPServer #Delete the files older than specified Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item I'd recommend creating the directories on a PC, putting this in Powershell ISE and just playing around with the code, see what sections do, how the cmlets work. I've learnt more through trial and error than any on course or in any book. 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now