cancel
Showing results for 
Search instead for 
Did you mean: 
KevinA
Retired GoTo Contributor

One2Many Script Repository

Welcome to the LogMeIn Central Script Repository!

 

What is it? A library of scripts to help you execute automated tasks and manage LogMeIn Pro² computers without having to access them manually.
 
How does it work? Simply browse the .txt files below, save as a .BAT file and head to your LogMeIn Central console. Then, navigate to the One2Many tab, and select "Run a batch file or executable." From there, simply upload the batch file and you're ready to go.
 
How can you help? We encourage you to share your own scripts and/or help review the scripts of others-- just "Kudo" your favorites or reply with your comments. 
 
Use of these scripts is at your own risk so please test them on a small number of systems before deploying at scale. The scripts are provided “as is” without any warranty of any kind and LogMeIn disclaims any and all liability regarding any use of the scripts.  Please see the following Terms and Conditions for more information.
 
 
Script Repository
 

Microsoft Updates

 

Windows Update Javascript- The following script will perform comprehensive Windows Updates (Windows and Microsoft updates) on remote computers.  This java script must be run as a Custom Task within One2Many with cscript being the entry point, Command to execute to update and install in the Custom Task is:

cscript.exe "%LMI_PACKAGEROOT%\wu.js" /sa /i

 

 

/sa will  find updates that are flagged to be automatically selected by Windows Update.  This is critical to avoid installing all available updates for the computer as this may include over ten 500Mb language support files on Vista and Win7. /i is the command argument that instructs the script to download and install the updates found.  Additional arguments are outlined within the source code of the JavaScript. 

 

Both the script and the command to execute can be customized to suite your environment’s needs.

 


Security
 
Disable Firewall- disable the Microsoft Windows Firewall for the appropriate version of Windows. 
Enable Firewall-  enable the Microsoft Windows Firewall for the appropriate version of Windows. 
Install AVI Convert-  install the LogMeIn Rescue AVI Converter which converts LogMeIn Rescue .rcec
 recordings to .avi, for the appropriate version of Windows.
Update AVG Virus Definitions: Updates your AVG (versions 8 and/or 9) virus definition files 
 
 
Maintenance
 
Purge DLL Cachedelete and restore the cache folder associated with Microsoft System File Checker for the 
  appropriate version of Windows.
Reboot- reboot the remote device(s) with a end user notification for the appropriate version of Windows.
Shut downshutdown the remote device(s) immediately for the appropriate version of Windows.
Reset System Restore-  reset (disable/enable) Microsoft System Restore for the appropriate version of 
  windows.
Turn Off System Restore- disable Microsoft System Restore for the appropriate version of windows.
Turn On System Restore- enable Microsoft System Restore for the appropriate version of windows.
Defrag- Defragments C volume
Spool Cleaner- Cleans print spooler (submitted by iDevelop)
LogMeIn UpdateUpdates host software with the latest version of LogMeIn. 

 

 

Use of these scripts is at your own risk so please test them on a small number of systems before deploying at scale. The scripts are provided “as is” without any warranty of any kind and LogMeIn disclaims any and all liability regarding any use of the scripts.  Please see the following Terms and Conditions for more information.
 
(edited and updated 8/21/19 by GlennD)
Tags (1)
132 REPLIES 132
rcolbert1971
New Contributor

Not sure of your set up however if you set up WSUS on the server and then make a GPO for the machines to look to that server for updates, its just a matter of approving the updates and the machines pulling them down.

GPO is the best method by far,

TempLogin123
New Contributor

Hi all

 

Posted in Central forum as well but thought I better had try here as well..

 

Need to pull back around 10 XMLs from different locations on remote PC and transfer back to my (approx 500 PC's in Estate) - I can create a batch file will pulls all the XMLs into one location if required but how to a get that zip file back to my PC?

tarcis
Active Contributor

Here is a script to clean the temp folder

 

@echo off

cd %temp%

rd . /q /s

marcjfernandez
New Contributor

Hi there...

 

I am new to this script aspect and we want to use OneToMany to install a software.  But the software uses prompts or "wizard" to install. i.e click Next a few times etc...  Does anybody know how I can write a script to "mimic" a person actually doing these steps?

 

Any help would be appreciated.

cmjones0822
New Contributor

Does anyone have a script that removes Shut Down from Start Menu but keep Restart? www.sevenforums.com/tutorials/148605-shut-down-restart-sleep-hibernate-commands-add-remove.html

Taomyn
Active Contributor

Any chance of an updated script to update the LMI client? Apart from being badly written (goto's and even worse duplicate labels), it doesn't work - all it does is re-run the last downloaded update file which of course is what is already running. If anyone knows how to kick off the update check and download, I'll happily add it to my amended script and share it here.
MarioAguadoFdz
Active Contributor

Hello regarding how to Force the LMI Host to be updated on demand, I has been asking for that to Logmein Support since more that 2 years ago, but nothing.

 

Under Central should bea  predefined task or a way to Trigger the Logmein Host update On-Demand for one or many Hosts at the same time, becuase I notice that not all our Host are udpated and we have 3723 Hosts:

 

  • LogMeIn Host Software Versions
Number of Host --> Software Version
1--> 2504
2--> 2651
1--> 2694
8--> 3268
8--> 3430
5--> 3888
13--> 4132
2--> 4144
12--> 4306
9--> 4380
24--> 4400
2123--> 4408
200--> 4634
878--> 4652
717--> 4670

 

 

ilssupport
New Contributor

Hello, I appologize if this has been answered already.

 

I deploy about 5 installations a day to different clients and would like to automate the logmein installation process. My only issue with the deployment is that I can't specify what name it should use so that the PC is named properly. I have a batch file that runs on startup that requires user input and one of those inputs would be "Do you want to install Logmein?" followed by "What should this PC be called?". This would then use the name entered in as part of a silent installer for logmein in the background. I am unable to use the hostname of the PC as I cannot enter in for example "Test SD (Test DVR# 1)" as a valid hostname.

 

Is this possible?

 

Thanks in advance for you help.

cbr00t
New Contributor

Hi all,

 

I want to share a downloader&installer code that I used with LMI Tasks.

 

Program is a Non-Interactive File Downloader & Installer tool in .NET C# works on Windows systems.

This program is calling by a LogMeIn One2Many Task like this:

 

    Batch Type: Batch or Exe

    Program    : CNIPackageInstallerApp.exe

    Parameters : -of cnioutput.xml -dl ftp:!!user:pass@ftp.mydownloadserver.com!public!mypackage!MyProgramSetup.Ver1.3.exe,c:#lmidownloads#_MYPROGRAM.EXE -il c:#lmidownloads#_MYPROGRAMSETUP.EXE,!silent

 

This code is so useful for LMI Tasks. It works as Non-Interactive. All inputs are given from commandline and it writes operation output into given output xml file. If operation success program returns 0 as exitcode, and other if fails.

 

I use this code to deploy & update/install my products to our customers.

Program doesn't need an user interaction and GUI system.

Works fine on Windows XP and later that installed MS .NET Framework 4.0.

 

Code can be developed for other languages like Java, C++ ... etc and other systems.

 

Here is program codes (2 class):

 

Kernel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Text;
using System.Reflection;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Diagnostics;
using System.Threading;

public static class Kernel {
    public const char
        Delim_ArgSeperator = ';'
        , Delim_SubArgSeperator = ',';
    public const string
        ResultSection_Download = "Download"
        , ResultSection_Install = "Install";
    public static string[] startupArgs;
    static bool runStatus;
    static Exception lastError;
    static TimeSpan beginTime, endTime;
    static CDict<string, CDict<string, string>> section2OutputDict;
    static FileInfo outputFile;
    static List<KeyValuePair<string, string>> downloadURLsAndTargets, installFilesAndArguments;

    #region Kernel Startup
    /// <summary>The main entry point for the application</summary>
    [STAThread]
    static int Main( string[] args ) {
        int exitCode;

        try { Application.EnableVisualStyles(); } catch { }
        try { Application.SetCompatibleTextRenderingDefault( false ); } catch { }

        startupArgs = new string[0];
        if (args != null && args.Length > 1) {
            startupArgs = new string[args.Length];
            for (var i = 0; i < startupArgs.Length; i++)
                startupArgs[i] = args[i].Replace( '!', '/' ).Replace( '#', '\\' ).Replace( '?', ' ' );
            //startupArgs = new string[args.Length - 1];
            //Array.Copy( args, 1, startupArgs, 0, startupArgs.Length );
        }
        
        initializeGlobals();
        beginTime = DateTime.Now.TimeOfDay;
        try { exitCode = run( args ); }
        catch (Exception ex) { exitCode = handleFatalError( ex ); }
        endTime = DateTime.Now.TimeOfDay;
        dumpOutput();
        return exitCode;
    }

    public static int run( string[] args ) {
        loadConfig();
        initializeStartup();
        if (downloadURLsAndTargets.Count > 0)
            downloadFiles();
        if (installFilesAndArguments.Count > 0)
            installFiles();
        return ( runStatus ? 0 : 2 );
    }
    #endregion

    #region Islem
    static void downloadFiles() {
        const int
            BufferSize = 1024 * 256
            , MaxTryCount = 3
            , ErrorWaitTimeMS = 1500;

        foreach (var kv in downloadURLsAndTargets) {
            int tryCount = -1;
            string url;
            FileInfo targetFile;
            WebRequest req = null;
            Stream webSrm = null, fileSrm = null;
            WebResponse resp = null;
            byte[] buffer = null;
            int bytes;

        redownload:
            tryCount++;
            url = kv.Key;
            targetFile = new FileInfo( kv.Value );
            try { req = WebRequest.Create( url ); }
            catch (Exception ex) {
                try { req.Abort(); } catch { }

                if (tryCount < MaxTryCount) {
                    Thread.Sleep( ErrorWaitTimeMS );
                    goto redownload;
                }

                runStatus = false;
                outputDownloadResult( url, "connect_fail " + ex.Message );
                continue;
            }

            try {
                if (req is FtpWebRequest) {
                    ( (FtpWebRequest)req ).Method = WebRequestMethods.Ftp.DownloadFile;
                    ( (FtpWebRequest)req ).UsePassive = true;
                    ( (FtpWebRequest)req ).UseBinary = true;
                }
                else if (req is HttpWebRequest) {
                    ( (HttpWebRequest)req ).Method = WebRequestMethods.Http.Get;
                }
                else {
                    try { req.Abort(); } catch { }

                    if (tryCount < MaxTryCount) {
                        Thread.Sleep( ErrorWaitTimeMS );
                        goto redownload;
                    }

                    runStatus = false;
                    outputDownloadResult( url, "invalid_protocol" );
                    continue;
                }
try { resp = req.GetResponse(); webSrm = resp.GetResponseStream(); } catch (Exception ex) { try { req.Abort(); } catch { } if (tryCount < MaxTryCount) { Thread.Sleep( ErrorWaitTimeMS ); goto redownload; } runStatus = false; outputDownloadResult( url, "response_read_error " + ex.Message ); continue; } if (!targetFile.Directory.Exists) { targetFile.Directory.Create(); targetFile.Refresh(); } fileSrm = targetFile.Open( FileMode.Create, FileAccess.ReadWrite, FileShare.Read ); buffer = new byte[BufferSize]; try { while (( bytes = webSrm.Read( buffer, 0, buffer.Length ) ) > 0) fileSrm.Write( buffer, 0, bytes ); } catch (Exception ex) { try { req.Abort(); } catch { } if (fileSrm != null) fileSrm.Close(); targetFile.Refresh(); if (targetFile.Exists) { targetFile.Delete(); targetFile.Refresh(); } //if (ex is WebException && ( (WebException)ex ).Status == WebExceptionStatus.UnknownError) { if (tryCount < MaxTryCount) { Thread.Sleep( ErrorWaitTimeMS ); goto redownload; } runStatus = false; outputDownloadResult( url, "download_error " + ex.Message ); continue; } outputDownloadResult( url, "success" ); } finally { if (buffer != null) { Array.Resize( ref buffer, 1 ); buffer = null; } if (fileSrm != null) fileSrm.Close(); if (webSrm != null) webSrm.Close(); if (resp != null) resp.Close(); if (req != null) { try { req.Abort(); } catch { } } } } } static void installFiles() { foreach (var kv in installFilesAndArguments) { FileInfo file; string args; ProcessStartInfo psi; Process pr; file = new FileInfo( kv.Key ); args = kv.Value; if (!file.Exists) { runStatus = false; outputInstallResult( file.FullName, "file_notfound" ); continue; } psi = new ProcessStartInfo( file.FullName, args ); psi.UseShellExecute = false; psi.CreateNoWindow = true; if (( pr = Process.Start( psi ) ) == null) { runStatus = false; outputInstallResult( file.FullName, "processstart_failed" ); continue; } pr.WaitForExit(); outputInstallResult( file.FullName, "success_exitcode " + pr.ExitCode.ToString() ); } } #endregion #region Error Handler public static int handleFatalError( Exception ex ) { setLastError( ex ); return 99; } #endregion #region Std I/O static void dumpOutput() { StringBuilder sb; string outputData; FileStream srm; sb = new StringBuilder(); writeXMLOutputDataTo( new StringWriter( sb ) ); outputData = sb.ToString(); if (runStatus) Console.Out.Write( outputData ); else Console.Error.Write( outputData ); if (outputFile != null) { if (outputFile.Exists) { outputFile.Delete(); outputFile.Refresh(); } File.WriteAllText( outputFile.FullName, outputData, Encoding.Default ); } } static void writeXMLOutputDataTo( TextWriter sw ) { Exception currentError; currentError = lastError; if (currentError != null && currentError.InnerException != null) currentError = currentError.InnerException; sw.WriteLine( string.Format( @"<?xml version=""1.0"" encoding=""{0}"" ?>", Encoding.Default.BodyName ) ); sw.WriteLine( @"<RunResult>" ); sw.WriteLine( string.Format( @" <RunStatus>{0}</RunStatus>", runStatus ? "success" : "fail" ) ); sw.WriteLine( @" <SystemInfo>" ); sw.WriteLine( string.Format( @" <MachineName>{0}</MachineName>", Environment.MachineName ) ); sw.WriteLine( string.Format( @" <DomainName>{0}</DomainName>", Environment.UserDomainName ) ); sw.WriteLine( string.Format( @" <UserName>{0}</UserName>", Environment.UserName ) ); sw.WriteLine( string.Format( @" <IsInteractiveMode>{0}</IsInteractiveMode>", Environment.UserInteractive.ToString() ) ); sw.WriteLine( string.Format( @" <OSBits>{0}</OSBits>", ( Environment.Is64BitOperatingSystem ? "x64" : "x86" ) ) ); sw.WriteLine( string.Format( @" <ProcessorBits>{0}</ProcessorBits>", ( Environment.Is64BitProcess ? "x64" : "x86" ) ) ); sw.WriteLine( string.Format( @" <ProcessorCount>{0}</ProcessorCount>", Environment.ProcessorCount.ToString() ) ); sw.WriteLine( string.Format( @" <ProcessCommandLine>{0}</ProcessCommandLine>", Environment.CommandLine ) ); sw.WriteLine( @" </SystemInfo>" ); sw.WriteLine( @" <Duration>" ); sw.WriteLine( string.Format( @" <BeginTime>{0}</BeginTime>", beginTime.ToString() ) ); sw.WriteLine( string.Format( @" <EndTime>{0}</EndTime>", endTime.ToString() ) ); sw.WriteLine( string.Format( @" <TotalSeconds>{0}</TotalSeconds>", ( endTime - beginTime ).ToString() ) ); sw.WriteLine( @" </Duration>" ); if (lastError == null) sw.WriteLine( @" <LastError />" ); else { sw.WriteLine( @" <LastError>" ); sw.WriteLine( string.Format( @" <Class>{0}</Class>", currentError.GetType().Name ) ); sw.WriteLine( string.Format( @" <Message>{0}</Message>", currentError.Message ) ); if (currentError is WebException) sw.WriteLine( string.Format( @" <Status>{0}</Status>", ( (WebException)currentError ).Status.ToString() ) ); else if (currentError is SocketException) sw.WriteLine( string.Format( @" <Status>{0}</Status>", ( (SocketException)currentError ).SocketErrorCode.ToString() ) ); else sw.WriteLine( @" <Status />" ); sw.WriteLine( string.Format( @" <StackTrace>{0}</StackTrace>", currentError.StackTrace ) ); sw.WriteLine( @" </LastError>" ); } sw.WriteLine( @" <Outputs>" ); primitiveWriteXMLOutputStringResult( sw, ResultSection_Download ); primitiveWriteXMLOutputStringResult( sw, ResultSection_Install ); sw.WriteLine( @" </Outputs>" ); sw.WriteLine( @"</RunResult>" ); sw.Flush(); } static void outputDownloadResult( string key, string value ) { primitiveOutputSuccessResult( ResultSection_Download, key, value ); } static void outputInstallResult( string key, string value ) { primitiveOutputSuccessResult( ResultSection_Install, key, value ); } static void setLastError( Exception ex ) { runStatus = false; lastError = ex; } static void primitiveWriteXMLOutputStringResult( TextWriter sw, string section ) { if (!section2OutputDict.ContainsKey( section ) || section2OutputDict[section].IsEmpty) sw.WriteLine( string.Format( @" <{0} />", section ) ); else { sw.WriteLine( string.Format( @" <{0}>", section ) ); foreach (var kv in section2OutputDict[section]) sw.WriteLine( string.Format( @" <item ref=""{0}"">{1}</item>", kv.Key, kv.Value ) ); sw.WriteLine( string.Format( @" </{0}>", section ) ); } } static void primitiveOutputSuccessResult( string section, string key, string value ) { section2OutputDict[section][key] = value; } #endregion #region Initialize static void initializeGlobals() { runStatus = true; lastError = null; section2OutputDict = new CDict<string, CDict<string, string>>(); foreach (var attr in new[] { ResultSection_Download, ResultSection_Install }) section2OutputDict[attr] = new CDict<string, string>(); } static void loadConfig() { string temp; outputFile = null; //downloadMode = ""; downloadURLsAndTargets = new List<KeyValuePair<string, string>>(); installFilesAndArguments = new List<KeyValuePair<string, string>>(); //if (( temp = scanArgValue( "-dm" ) ) != null) { // if (new[] { "", DownloadMode_FTP, DownloadMode_HTTP }.Contains( temp )) // downloadMode = temp; // else // throw new ArgumentOutOfRangeException( temp ?? "", "invalidstartuparg -dm" ); //} if (( temp = scanArgValue( "-of" ) ) != null) { outputFile = new FileInfo( temp ); } if (( temp = scanArgValue( "-dl" ) ) != null) { string[] parts, subParts; downloadURLsAndTargets = new List<KeyValuePair<string, string>>(); parts = temp.Split( new char[] { Delim_ArgSeperator }, StringSplitOptions.RemoveEmptyEntries ); foreach (var part in parts) { if (string.IsNullOrWhiteSpace( part )) continue; subParts = part.Split( new char[] { Delim_SubArgSeperator }, 2 ); downloadURLsAndTargets.Add( new KeyValuePair<string, string>( subParts[0], ( subParts.Length > 1 ? subParts[1] : "" ) ) ); } } if (( temp = scanArgValue( "-il" ) ) != null) { string[] parts, subParts; installFilesAndArguments = new List<KeyValuePair<string, string>>(); parts = temp.Split( new char[] { Delim_ArgSeperator }, StringSplitOptions.RemoveEmptyEntries ); foreach (var part in parts) { if (string.IsNullOrWhiteSpace( part )) continue; subParts = part.Split( new char[] { Delim_SubArgSeperator }, 2 ); installFilesAndArguments.Add( new KeyValuePair<string, string>( subParts[0], ( subParts.Length > 1 ? subParts[1] : "" ) ) ); } } } static void initializeStartup() { if (outputFile != null && !outputFile.Exists) { if (!outputFile.Directory.Exists) { outputFile.Directory.Create(); outputFile.Refresh(); } } } #endregion #region Yardimci static string scanArgValue( string arg ) { int index; string value; if (( index = Array.IndexOf( startupArgs, arg ) ) < 0) return null; return startupArgs[index + 1]; } #endregion }

 

CDict.cs

#region Using directives
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
#endregion

/// <summary>Standard CDict yapısı</summary>
[Serializable()]
public class CDict<TKey, TValue> : Dictionary<TKey, TValue> {
    #region Get/Set
    [TypeConverter( typeof( ExpandableObjectConverter ) )]
    public virtual TValue this[TKey key] {
        get {
            try { return base[key]; }
            catch (KeyNotFoundException e) { throw new KeyNotFoundException( string.Format( "KeyNotFound: [{0}]", key ), e ); }
        set {
            if (base.ContainsKey( key ))
                base[key] = value;
            else
                base.Add( key, value );
        }
    }
    public virtual bool IsEmpty {
        get { return this.Count == 0; }
    }
    #endregion

    public CDict() { }
    public CDict( params KeyValuePair<TKey, TValue>[] keyValueArray ) {
        this.Add( keyValueArray );
    }
    public CDict( IEnumerable<TKey> keys, IEnumerable<TValue> values ) {
        this.AddRange( keys, values );
    }
    public CDict( IDictionary<TKey, TValue> dict ) {
        this.AddRange( dict );
    }
    public TValue Add( TKey key, TValue value ) {
        this[key] = value;
        return value;
    }
    public void Add( params KeyValuePair<TKey, TValue>[] keyValueArray ) {
        foreach (var keyValuePair in keyValueArray)
            this.Add( keyValuePair.Key, keyValuePair.Value );
    }
    public CDict<TKey, TValue> AddRange( IEnumerable<TKey> _keys, IEnumerable<TValue> _values ) {
        var keys = new List<TKey>( _keys );
        var values = new List<TValue>( _values );
        if (keys != null && values != null && keys.Count == values.Count) {
            for (int i = 0; i < keys.Count; i++)
                this.Add(new KeyValuePair<TKey, TValue>(keys[i], values[i] ) );
        }
        return this;
    }
    public CDict<TKey, TValue> AddRange( IDictionary<TKey, TValue> dict ) {
        foreach (var kv in dict)
            Add( kv );
        return this;
    }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
        CDict<TKey, TValue>.Enumerator dictEnum = base.GetEnumerator();
        while (dictEnum.MoveNext())
            yield return dictEnum.Current;
    }
}

 

joelasaro
Active Contributor

The issue with not being able to update the LMI client from One2Many or any built-in function is especially bad when there is a bug in version 4634 that causes high cpu usage constantly (svchost.exe process) and there is no way to automatically force clients to update.

I have automatic updates enabled for all the LMI Pro clients and still have about a third of them on 4634 instead of 4670.

 

***Update:

 

I finally got to test the batch script for updating LMI and it seems to be working fine for me.  I used a condensed version of the script linked in the first post of this topic that I found on spiceworks:

http://community.spiceworks.com/scripts/show/2544-logmein-silent-update-heartbleed-counter

 

I just saved this as a .bat file and uploaded into a One2Many "Run a batch file or executable" type script.  When I run this the machine goes offline after a bit and stays offline for  a few minutes and then comes backonline one LMI is updated.  I have successfull update two machines so far this way with no issues. I upgraded from version 4634 to 4670.

 

Obviously, this functionality should be backed into LMI Central, but this is atleast usable in my experience so far.  Below is the script from the SpiceWorks post that I used.

 

@echo off
cd %TEMP%
if %PROCESSOR_ARCHITECTURE% equ AMD64 goto amd64
echo cd "%ProgramFiles%\logmein\x86\update" > lmiupdate.cmd
goto x86done
:amd64
echo cd "%ProgramFiles(x86)%\logmein\x64\update" > lmiupdate.cmd
:x86done
echo raupdate.exe /s >> lmiupdate.cmd
echo exit >> lmiupdate.cmd
REM Now it'll run it
start lmiupdate.cmd