Categorías
Powershell

Ejecutar un script de powershell como administrador

Si alguna vez has utilizado un script de powershell, y este requeria permisos de administrador, te habrás encontrado con un error parecido a este.

Suele ser debido a que debes ejecutar el script como administrador. Hay varias maneras de hacerlo, para un administrador de sistemas o para un usuario avanzado es algo tan simple como hacer botón derecho en el icono de windows (si hablamos de windows 10) y en el menú contextual que aparece, elegir la opción de «windows Powershell(Administrador)»

fijaros como ahora se ha abierto una ventana de powershell, pero que en podeis ver como pone «Administrador:», con lo cual todo lo que ejecutemos en dicha ventana se ejecutura como administrador. Ya solo quedaría poner la ruta del script ps1 que queremos ejecutar y pulsar enter.

El problema radica cuando quien lo tiene que ejecutar es un usuario «estandard» que no entiende de consolas, etc. Para este tipo de usuarios tenemos que preparar una solución mas simple.

Basicamente lo que haremos será crear un acceso directo al script que nos interesa ejecutar y darle a este acceso directo permisos de administrador, de este modo el usuario final solo tendrá que hacer un simple clic en el. Veamoslo.

Con el botón derecho en el escritorio o dentro de una carpeta (en su zona blanca), elegimos nuevo y luego acceso directo

En el acceso pondremos lo siguiente «powershell -File Rutacompletadelscript.ps1» sin las comillas.

Imaginemos que nuestro script se llama script1.ps1 y está en c:\temp, pondríamos algo tal que así powershell -File c:\temp\script1.ps1

Ya solo nos quedaría poner nombre al acceso directo

y por último, con el botón derecho sobre el acceso directo , ir a «acceso directo» «opciones avanzadas» y se nos abriá una ventana donde marcaremos la opción «ejecutar como administrador».

Ahora, cada vez que utilicemos nuestro acceso directo, ejecutara el script de powershell como administrador.

Dejad vuestros comentarios.

Categorías
Excel Powershell

Combinar varios excels en uno

Alguna vez has querido combinar varios excels en uno?. Una solución sería abrir un nuevo excel y luego todos los demas e ir moviendo en cada uno de los excels la primera hoja al excel que hemos creado para tal proposito. Esta solución puede ir bien cuando tenemos un par de excels que «unir» pero cuando son mas o lo tenemos que hacer repetidas veces, es más facil utilizar el script que os voy a enseñar a continuación.

Supongamos que en una carpeta tenemos varios excel como podeis ver en la imagen de más abajo. En el ejmplo tenemos que en la carpeta (1) c:\tmp\archivosexcel tenemos (2) tres archivos excel (3)(4) y (5), los cuales los queremos unir en uno solo.

Con el siguiente script de powershell podremos unirlos fácil y rapidamente.

#Abrimos una aplicación excel
$ExcelObject=New-Object -ComObject excel.application
$ExcelObject.visible=$true

#Cogemos los excels que queremos unir.
$ExcelFiles=Get-ChildItem -Path C:\tmp\archivosexcel

$Workbook=$ExcelObject.Workbooks.add()
$Worksheet=$Workbook.Sheets.Item("Hoja1")

foreach($ExcelFile in $ExcelFiles){
    #Abrimos cada hoja de cada fichero y la copiamos en nuestro nuevo excel.
    $Everyexcel=$ExcelObject.Workbooks.Open($ExcelFile.FullName,0,$true)
    $Everysheet=$Everyexcel.sheets.item(1)
    $Everysheet.Copy($Worksheet)
    $Everyexcel.Close()
 
}
#Grabamos nuestro excel que contiene los demas.
$Workbook.SaveAs("C:\tmp\archivosexcel\ExcelUnido.xlsx")
$ExcelObject.Quit()

Como podeis ver, el script es bastante sencillo. Hay cuatro partes diferenciadas. Primero abrimos una instancia del excel

Luego por una parte cogemos los ficheros que queremos unir y añadimos una hoja de excel en el archivo excel que habiamos creado en el primer paso.

A continuación, para cada uno de los ficheros de la carpeta, abrimos su primera hoja y la copiamos en libro que hemos creado al inicio. Una vez hecho esto cerramos el fichero excel del cual hemos copiado la hoja.

Por último, guardamos el libro que hemos utilizado para unir todos los demás excel y cerramos la instancia de excel que hemos utilizado.

El resultado de todo es un excel con todas las primeras hojas de los excels originarios.

Como habeis visto, este script solo copia la primera hoja de cada libro, con una pequeña modificación os podeis adaptar el script para que copie todas las hojas de cada de uno de los ficheros involucrados.

A continuación podeis ver un video con todo el proceso.

Dejad vuestra opinión sobre este script.

Categorías
Powershell

Mover ficheros de un directorio a otro siguiendo un determinado filtro

Supongamos que tenemos unos ficheros en unos directorios equivocados. Por ejemplo tenemos unas facturas guardadas por años. Para ello hemos creado una carpeta por cada año, 2020,2021,etc y dentro de cada carpeta, hemos creado a su vez otra carpeta con el numero de nuestro cliente, por ejemplo el 27. Finalmente, en esta carpeta hemos metido la factura F.20.1234.pdf, pero nos hemos dado cuenta que no está en la carpeta correcta, puesto que pertenece al año 2020 (F.20.1234.pdf) y no al 2021 donde hemos dejado el documento.

En la imagen inferior vemos como quedaría.

Evidentemente si solo fuera un fichero no sería un problema pero si fueran decenas, cientos o incluso miles, sería una tarea laboriosa ir uno a uno pasando de una carpeta a otra. Para más inri, en la carpeta 2020 no hemos ni creado la carpeta del cliente, con lo que aún sería más laborioso.

Para evitar todo este trabajo os dejo un script de powershell que hara el trabajo por vosotros. En el simplemente teneis que el valor de las variables $oldyear,$newyear,$basedir y $nameToFind para que se ajuste a vuestro caso.

En mi caso oldeyear representa la carpeta 2020, newyear la 2021 (pero en el vuestro podría ser una zona, país, o cualquier otra cosa), en basedir deberías de cambiar c:\tmp\ejemplo a vuestra ruta donde tuvieses los ficheros a cambiar. Para terminar en NameToFind poneis la cadena de texto común a todos los ficheros que quereis seleccionar, en mi caso las facturas que empiezan por F.20.

Más abajo podeis ver el script que os moverá todos los ficheros que estén en subcarpetas a partir de la carpeta $newyear->2021 y moverá los ficheros a $oldyear->2020, esto lo hara buscando en las subcarpetas y además estas subcarpetas las creará en la carpeta $oldyear si no existen.

$oldyear="2020"
$newyear="2021"
$baseDir = "c:\tmp\ejemplo\$newyear\"
#Filtraremos por ficheros que empiecen por
$NameToFind = "F.20."
#buscamos en la carpeta del 2021 los ficheros que cumplan el criterio, aunque esten en subdirectorios!!!
$filesMatching = Get-ChildItem $BaseDir -Recurse | Where-Object { $_.PSIsContainer -eq $false -and $_.Name.Contains($NameToFind) } 

$dirUnSorted=@()
foreach($file in $filesMatching){
    #Write-Host $file.Directory.Name
    $dirUnSorted+=$file.Directory.Name
}
#now we make unique the parent's directories
$dirSorted= $dirUnSorted | Sort-Object | Get-Unique




$(foreach($dir in $dirSorted){

   #si no existe el directorio lo creamos
   If(!(test-path "c:\tmp\ejemplo\$oldyear\$dir\"))
   {
      New-Item -ItemType Directory -Force -Path "c:\tmp\ejemplo\$oldyear\$dir\"
   }
   #movemos los elementos que cumplan en criterio
   move-item -Path "c:\tmp\ejemplo\$newyear\$dir\F.20.*.pdf" -Destination "c:\tmp\ejemplo\$oldyear\$dir\"  -PassThru
}) 

y el resultado final es este, donde podeis ver que se ha creado la carpeta 27 y en ella se ha movido el fichero F.20.1234.pdf.

En la salida del powershell podeis ver como el fichero se ha movido de una carpeta a otra.

Este script os puede ayudar a mover ficheros de una carpeta a otra siguiendo vuestro criterio sin tener que hacerlo manualemnte. Dejad vuestros comentarios.

Categorías
Powershell

Obtener los 10 ficheros mas grandes

Si alguna vez os habiais planteado como «encontrar» los 10 ficheros mas grandes en vuestro sistema, a continuación podreis verlo mediante powershell.

Tanto por curiosidad como si los quereis encontrar para ganar espacio, mediante el siguiente comando, podreis encontrar los ficheros que mayor tamaño tienen en vuestro sistema y así tomar las decisiones oportunas.

El comando de más abajo, os mostrará los 10 ficheros mas grandes, respecto el directorio que esteis (ya que no se ha introducido ninguno, despues de gci)

gci -r | sort -descending -property length | select -first 10 name, length

A continuación podeis ver un ejemplo del resultado que nos mostraria.

Como podeis ver, como nos econtrabamos en c:\windows\system32, nos muestra los ficheros mas grandes de esta y sus subcarpetas. Evidentemente con cambiar el «-first 10» por cualquier otro valor, nos mostraría los elementos que quisieramos mostrar.

Otra variante del comando, nos podria ofrececer el tamaño en Gigas, de este modo es mas comodo para los humanos

gci -r | sort -descending -property length | select -first 10 name, @{Name="Gigabytes";Expression={[Math]::round($_.length / 1GB, 2)}}

El resultado seria el siguiente

Por último una variante interesante seria añadir al comando el parametro fullname para que nos mostrara el full path de los ficheros para de este modo poder operar con ellos.

gci -r | sort -descending -property length | select -first 10 name, @{Name="Gigabytes";Expression={[Math]::round($_.length / 1GB, 2)}}, fullname

El resultado final sería:

Espero que os haya gustrado la entrada, dejad vuestros comentarios.

Categorías
Powershell

Error 0xFFFD0000 al ejecutar powershell en tareas programadas

Si os sale el error 0xFFFD0000 al ejecutar un powershell desde tareas programadas, se debe a que la ruta del script no es la correcta. Si lo volveis a comprobar y veis que la ruta parece la correcta, seguramente será que tendreis que poner entre «» la ruta para para escapar los espacios.

Ejemplo del error

Por ejemplo, si tenemos un fichero en c: llamado script espacio.ps1 habría que ponerlo tal que así

De este modo evitamos que nos de error debido a los espacios en la ruta.

Categorías
Powershell Windows

Como ejecutar un script de powershell de manera programada

Para programar la ejecución de scripts de powershell, deberemos hacer lo siguiente. (1)Iremos al buscador de windows y escribiremos programar(2). Nos saldrá el icono de «Programador de tareas»(3), donde haremos clic.

Crearemos una tarea programada, para lo cual, pulsaremos botón derecho sobre Programador de tareas(local)(1), y elegiremos (2)Crear tarea…

Nos aparecerá la ventana de la tarea con varias pestañas. Nos centraremos en General, Desencadenadores y Acciones.

En general, pondremos un nombre a la tarea(1). Luego elegiremos «Ejecutar tanto si el usuario inició sesión como si no»(2), para que se ejecute como servicio, y no solo cuando se haga login. Por último, si vamos a borrar ficheros que requieran permisos de administrador, elegiremos «Ejecutar con los privilegios más altos»(3). Al darle aceptar nos preguntará el user y pwd para que se pueda ejecutar de modo desatendido.

Pasaremos a Desencadenadores (1), donde elegiremos cuando ejecutarlo. Para ello, haremos clic en Nuevo(2), elegiremos en «iniciar la tarea» «según una programación»(3) y más abajo(4) le diremos la programación que queremos.

Y finalmente, le indicaremos que script queremos ejecutar. Iremos a (1) Acciones, luego (2)Nuevo y en programa(3) pondremos powershell, luego, en «Agregar argumentos(opcional)»(4) pondremos -f RUTACOMPLETADELSCIPT.ps1 por ejemplo si nuestro ficheros se llama ejemplo.ps1 y está en c:\tmp sería -f c:\tmp\ejemplo.ps1

Luego dariamos a aceptar a la acción y a la tarea, y ya la tendríamos lista para ser ejecutada cada dia a las 17:05:22

Acordaros de dejar vuestro comentario.

Categorías
Powershell Sin categoría

Borrar ficheros más antiguos que una fecha dada

Con powershell podemos realizar facilmente esta tarea. Hay veces que nos interesa borrar de un directorioo (y sus subdirectorios), los ficheros que hayan sido modificados hace mas de un mes (por ejemplo). Además veremos como ejecutar este script de manera programada.

Empezemos con el script de powerhshell que nos permitirá borrar los ficheros mas antiguos que diez dias. (este valor lo podeis cambiar con la variable Daysold

$Daysold = 10
$Folder = "c:\windows\temp"

#Borramos los ficheros que haya en la Variable Folder, que sean mas viejos que Daysold
Get-ChildItem $Folder -Recurse -Force -ea 0 |
? {!$_.PsIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-$Daysold)} |
ForEach-Object {
   $_ | del -Force
   $_.FullName | Out-File C:\tmp\deletedlog.txt -Append
}

#Eliniar directorios vacios
Get-ChildItem $Folder -Recurse -Force -ea 0 |
? {$_.PsIsContainer -eq $True} |
? {$_.getfiles().count -eq 0} |
ForEach-Object {
    $_ | del -Force
    $_.FullName | Out-File C:\tmp\deletedlog.txt -Append
}
#Los nombres de los ficheros eliminados los guardamos en C:\tmp\deletedlog.txt por si queremos tracearlo.

Como podeis ver en el código, tenemos dos variables, Folder y Daysold, que hacen referencia a la carpeta donde queremos borrar todos los ficheros, cuya fecha de modificación es mayor de 10 dias que es el valor de Daysold.

Al ejecutar este script, el primer bloque eliminará todos los ficheros mas antiguos de 10 dias, y después la seguna parte del script eliminará los directorios que se hayan quedado vacios. Si queremos dejar los directorios vacios, solo tenemos que eliminar las lineas de la 13 a la 19, que se encargan del borrado de los mismos.

Por otra parte guardamos el nombre de los ficheros borradoes en el fichero C:\tmp\deletedlog.txt por si queremos tener un log del borrado realizado.

Si quereis programar el script, lo podeis hacer facilmente siguiendo este artículo. Como ejecutar un script de powershell de manera programada

Espero que os haya gustado el artículo. Dejad vuestros comentarios!!

Categorías
Powershell

Como separar pdfs con PowerShell

A continuación os voy a enseñar como separar las páginas de un pdf mediante pdf. Lo haremos con la ayuda del módulo PSWritePDF, con el, podremos separar los pdfs facilmente para extraer las páginas que más nos interese.

Primero, vayamos a la instalación del módulo, para ello escribiremos en la consola de PowerShell, PS C:\WINDOWS\system32> Install-Module PSWritePDF -Force Si no tenemos instalado el proveedor de Nuget, nos pedirá instalarlo, le diremos que si, y finalmente instalará el módulo.

Una vez instalado, separar un pdf es tan simple como PS C:\Users\lacajadeinternet\Downloads> split-PDF -FilePath «C:\Users\lacajadeinternet\Downloads\Archivopdf.pdf» -OutputFolder «$PSScriptRoot\Output». El primer parámetro -FilePath es para el fichero pdf, el segundo -OutputFolder para la carpeta de salida donde queremos que nos separe los ficheros.